Gestisci indici

Firestore garantisce le prestazioni delle query richiedendo un indice per ogni query. Gli indici richiesti per le query più semplici vengono creati automaticamente per te. Mentre utilizzi e testi l'app, Cloud Firestore genera messaggi di errore che ti aiutano a creare ulteriori indici richiesti dall'app. Questa pagina descrive come gestire gli indici a campo singolo, composti e [vettore][vettore].

Creare un indice mancante tramite un messaggio di errore

Se provi a eseguire una query composta con una clausola di intervallo che non è mappata a un indice esistente, viene visualizzato un errore. Il messaggio di errore include un link diretto per creare l'indice mancante nella console Firebase.

Segui il link generato alla console Firebase, controlla le informazioni compilate automaticamente e fai clic su Crea.

Se è necessario un indice di vettore, il messaggio di errore includerà un comando Google Cloud CLI per creare l'indice di vettore mancante. Esegui il comando per creare l'indice mancante.

Ruoli e autorizzazioni

Prima di poter creare un indice in Firestore, assicurati di avere uno dei seguenti ruoli:

  • roles/datastore.owner
  • roles/datastore.indexAdmin
  • roles/editor
  • roles/owner

Se hai definito ruoli personalizzati, assegna tutte le seguenti autorizzazioni per creare gli indici:

  • datastore.indexes.create
  • datastore.indexes.delete
  • datastore.indexes.get
  • datastore.indexes.list
  • datastore.indexes.update

Utilizzare la console di Google Cloud Platform

Dalla console di Google Cloud Platform, puoi gestire le esenzioni dall'indicizzazione di un singolo campo e gli indici compositi.

Crea un indice composto

Per creare manualmente un nuovo indice composto dalla console Google Cloud:

  1. Nella console Google Cloud, vai alla pagina Database.

    Vai a Database

  2. Seleziona il database richiesto dall'elenco dei database.

  3. Nel menu di navigazione, fai clic su Indici e poi sulla scheda Composto.

  4. Fai clic su Crea indice.

  5. Inserisci un ID raccolta. Aggiungi i nomi dei campi da indicizzare e una modalità di indicizzazione per ogni campo. Fai clic su Salva indice.

Il nuovo indice verrà visualizzato nell'elenco degli indici composti e Firestore inizierà a crearlo. Al termine della creazione, vedrai un segno di spunta verde accanto all'indice.

Eliminare un indice composto

Per eliminare un indice composito:

  1. Nella console Google Cloud, vai alla pagina Database.

    Vai a Database

  2. Seleziona il database richiesto dall'elenco dei database.

  3. Nel menu di navigazione, fai clic su Indici e poi sulla scheda Composto.

  4. Nell'elenco degli indici compositi, fai clic sul pulsante Altro per l'indice da eliminare. Fai clic su Elimina.

  5. Conferma di voler eliminare l'indice facendo clic su Elimina indice nell'avviso.

Aggiungere un'esenzione dell'indice a campo singolo

Le esenzioni dell'indice a campo singolo ti consentono di eseguire l'override delle impostazioni dell'indice automatico per campi specifici di una raccolta. Puoi aggiungere un'esenzione a campo singolo dalla console:

  1. Nella console Google Cloud, vai alla pagina Database.

    Vai a Database

  2. Seleziona il database richiesto dall'elenco dei database.

  3. Nel menu di navigazione, fai clic su Indici e poi sulla scheda Campo singolo.

  4. Fai clic su Aggiungi esenzione.

  5. Inserisci un ID raccolta e un Percorso campo.

  6. Seleziona le nuove impostazioni di indicizzazione per questo campo. Abilita o disabilita gli indici a campo singolo in ordine crescente, decrescente e contenenti array aggiornati automaticamente per questo campo.

  7. Fai clic su Salva esenzione.

Aggiungere un'esenzione a livello di raccolta

Per definire un'esenzione dell'indice a campo singolo che si applica a tutti i campi di un ID raccolta:

  1. Fai clic su Aggiungi esenzione.
  2. Inserisci un ID raccolta per il gruppo di raccolte e imposta Percorso campo su *.

    Scegli il campo da esentare

  3. Seleziona le esenzioni dall'indicizzazione da applicare a tutti i campi del gruppo di raccolte.

  4. Fai clic su Salva esenzione.

Eliminare un'esenzione dell'indice a campo singolo

Per eliminare un'esenzione dell'indice a campo singolo:

  1. Nella console Google Cloud, vai alla pagina Database.

    Vai a Database

  2. Seleziona il database richiesto dall'elenco dei database.

  3. Nel menu di navigazione, fai clic su Indici e poi sulla scheda Campo singolo.

  4. Nell'elenco delle esenzioni dall'indice a un campo, fai clic sul pulsante Altro per l'esenzione che vuoi eliminare. Fai clic su Elimina.

  5. Conferma di voler eliminare questa esenzione facendo clic su Elimina nell'avviso.

Quando elimini un'esenzione a campo singolo, il campo o il sottocampo specificato userà le impostazioni di indicizzazione ereditate. I campi del documento tornano alle impostazioni degli indici automatici del database. I campi secondari in una mappa ereditano eventuali esenzioni per i campi principali prima di ereditare le impostazioni dell'indice automatico.

Utilizza l'interfaccia a riga di comando di Firebase

Puoi anche eseguire il deployment degli indici con l'interfaccia a riga di comando di Firebase. Per iniziare, esegui firebase init firestore nella directory del progetto. Durante la configurazione, Firebase CLI genera un file JSON con gli indici predefiniti nel formato corretto. Modifica il file per aggiungere altri indici e esegui il deployment con il comando firebase deploy.

Per eseguire il deployment solo di indici e regole Firestore, aggiungi il flag --only firestore.

Se apporti modifiche agli indici utilizzando la console Firebase, assicurati di aggiornare anche il file degli indici locali. Fai riferimento al riferimento alla definizione dell'indice JSON.

Utilizza Terraform

Creazione di indici nel database

I database Firestore possono includere indici a campo singolo e composti. Puoi modificare il file di configurazione Terraform per creare un indice per il tuo database. Gli indici a campo singolo e composti utilizzano tipi di risorse Terraform distinti (google_firestore_index e google_firestore_field).

Sono supportati sia gli indici in modalità Native che in modalità Datastore di Firestore.

Indice a campo singolo

Il seguente esempio di file di configurazione Terraform crea un indice a campo singolo sul campo name nella raccolta chatrooms:

firestore.tf

resource "random_id" "variable"{
  byte_length = 8
}

resource "google_firestore_field" "single-index" {
  project = "project-id"
  database = "database-id"
  collection = "chatrooms_${random_id.variable.hex}"
  field = "name"

  index_config {
    indexes {
        order = "ASCENDING"
        query_scope = "COLLECTION_GROUP"
    }
    indexes {
        array_config = "CONTAINS"
    }
  }

  ttl_config {}
}
  • Sostituisci project-id con l'ID progetto. Gli ID progetto devono essere univoci.
  • Sostituisci database-id con l'ID del tuo database.

Indice composto

Il seguente esempio di file di configurazione Terraform crea un indice composto per una combinazione del campo name e del campo description nella raccolta chatrooms:

firestore.tf

resource "google_firestore_index" "composite-index" {
  project = "project-id"
  database = "database-id"

  collection = "chatrooms"

  fields {
    field_path = "name"
    order      = "ASCENDING"
  }

  fields {
    field_path = "description"
    order      = "DESCENDING"
  }

}
  • Sostituisci project-id con l'ID progetto. Gli ID progetto devono essere univoci.
  • Sostituisci database-id con l'ID del tuo database.

Indice vettoriale

Il seguente esempio di file di configurazione Terraform crea un indice di vettore sul campo embedding nella raccolta chatrooms:

firestore.tf

resource "google_firestore_index" "vector-index" {
  project = "project-id"
  database = "database-id"
  collection = "chatrooms"

  fields {
    field_path = "__name__"
    order = "ASCENDING"
  }

  fields {
    field_path = "embedding"
    vector_config {
      dimension = 128
      flat {}
    }
  }
}
  • Sostituisci project-id con l'ID progetto. Gli ID progetto devono essere univoci.
  • Sostituisci database-id con l'ID del tuo database.

Indici in modalità Datastore

Puoi anche creare indici in modalità Datastore utilizzando Terraform.

datastore.tf

resource "google_firestore_index" "datastore-mode-index" {
  project = "project-id"
  database = "database-id"

  collection = "chatrooms"

  fields {
    field_path = "name"
    order      = "ASCENDING"
  }

  fields {
    field_path = "description"
    order      = "DESCENDING"
  }

  query_scope = "COLLECTION_GROUP"
  api_scope   = "DATASTORE_MODE_API"
}
Eseguire la migrazione da google_datastore_index

La risorsa google_datastore_index è deprecata e non sarà disponibile in terraform-provider-google 6.0.0 e versioni successive.

Se in precedenza utilizzavi la risorsa google_datastore_index, puoi eseguire la migrazione a google_firestore_index. Per eseguire la migrazione:

  1. Scrivi una risorsa google_firestore_index equivalente.
  2. Importa l'indice esistente in modalità Datastore nella nuova risorsa.
  3. Rimuovi i riferimenti alla vecchia risorsa google_datastore_index.
  4. Rimuovi la vecchia risorsa google_datastore_index dallo stato di Terraform.
  5. Esegui terraform apply per applicare eventuali modifiche.

Di seguito sono riportate istruzioni più dettagliate:

  1. Scrivi un google_firestore_index sostitutivo in base alla risorsa google_datastore_index esistente. Consulta di seguito per le modifiche richieste.
  2. Determina il percorso della risorsa Firestore dell'indice:

    export INDEX_RESOURCE_PATH=$(echo '"projects/${google_datastore_index.datastore-index-resource-name.project}/databases/(default)/collectionGroups/${google_datastore_index.datastore-index-resource-name.kind}/indexes/${google_datastore_index.datastore-index-resource-name.index_id}"' | terraform console | tr -d '"')
    

    Sostituisci datastore-index-resource-name con il nome Terraform della risorsa esistente.

  3. Importa l'indice della modalità Datastore esistente nella risorsa google_firestore_index creata sopra:

    terraform import google_firestore_index.firestore-index-resource-name $INDEX_RESOURCE_PATH
    

    Sostituisci firestore-index-resource-name con il nome Terraform della risorsa esistente.

    Per ulteriori informazioni sull'importazione delle risorse di indicizzazione di Firestore, consulta la documentazione di riferimento di google_firestore_index.

  4. Elimina la risorsa google_datastore_index esistente dal file di configurazione Terraform.
  5. Rimuovi la risorsa google_datastore_index esistente dallo stato di Terraform:

    terraform state rm google_datastore_index.datastore-index-resource-name
    

    Per ulteriori informazioni sulla rimozione delle risorse, consulta la pagina di Terraform relativa alla rimozione delle risorse.

  6. Esegui terraform plan. Verifica l'output per confermare che non stai creando né distruggendo risorse.

    Controlla l'output per assicurarti che l'importazione sia stata completata correttamente. Se l'output mostra la modifica di alcuni campi, assicurati che queste modifiche siano intenzionali. Se l'output include una riga simile alla seguente:

    google_firestore_index.firestore-index-resource-name must be replaced
    

    quindi controlla il file di configurazione Terraform per verificare se sono stati commessi errori.

  7. Una volta soddisfatti dell'output del piano Terraform, esegui:

    terraform apply
    

  8. Tradurre l'indice

    Per tradurre una risorsa google_datastore_index nella risorsa google_firestore_index equivalente, copiala e apporta le seguenti modifiche:

    • Sostituisci google_datastore_index con google_firestore_index.
    • Sostituisci il nome dell'argomento kind con collection, ma mantieni invariato il valore dell'argomento.
    • Sostituisci il nome dell'argomento ancestor con query_scope. Sostituisci il valore dell'argomento ALL_ANCESTORS con COLLECTION_RECURSIVE e qualsiasi altro valore con COLLECTION_GROUP. Se non è presente l'argomento ancestor, aggiungi un argomento query_scope con valore COLLECTION_GROUP.
    • Aggiungi l'argomento api_scope con il valore DATASTORE_MODE_API.
    • Per ogni istanza di properties, sostituiscila con un'istanza corrispondente di fields. Sostituisci ogni istanza di name con field_path e ogni istanza di direction con order.

    Ad esempio, considera questa risorsa google_datastore_index:

    datastore.tf

    resource "google_datastore_index" "legacy" {
      kind = "foo"
    
      properties {
        name = "property_a"
        direction = "ASCENDING"
      }
    
      properties {
        name = "property_b"
        direction = "ASCENDING"
      }
    }
    

    La risorsa google_firestore_index equivalente è:

    resource "google_firestore_index" "new" {
      // note: defaults to the provider project
      project = project
    
      // note: defaults to the (default) database
      database = "(default)"
    
      collection = "foo"
    
      api_scope = "DATASTORE_MODE_API"
    
      // since there was no "ancestor" property set above, use COLLECTION_GROUP here
      query_scope = "COLLECTION_GROUP"
    
      fields {
        field_path = "property_a"
        order  = "ASCENDING"
      }
    
      fields {
        field_path = "property_b"
        order = "ASCENDING"
      }
    }
    

    Tempo di compilazione dell'indice

    Per creare un indice, Firestore deve configurarlo e poi eseguire il suo completamento con i dati esistenti. Il tempo di compilazione dell'indice è la somma del tempo di configurazione e del tempo di backfill:

    • La configurazione di un indice richiede alcuni minuti. Il tempo di compilazione minimo per un indice è di alcuni minuti, anche per un database vuoto.

    • Il tempo necessario per il backfill dipende dalla quantità di dati esistenti appartenenti al nuovo indice. Maggiore è il numero di valori di campo che corrispondono alla definizione dell'indice, maggiore è il tempo necessario per eseguire il backfill dell'indice.

    Le build degli indici sono operazioni a lunga esecuzione.

    Dopo aver avviato una compilazione dell'indice, Firestore assegna all'operazione un nome univoco. I nomi delle operazioni sono preceduti da projects/[PROJECT_ID]/databases/(default)/operations/, ad esempio:

    projects/project-id/databases/(default)/operations/ASA1MTAwNDQxNAgadGx1YWZlZAcSeWx0aGdpbi1zYm9qLW5pbWRhEgopEg
    

    Tuttavia, puoi omettere il prefisso quando specifichi un nome dell'operazione per il comando describe.

    Elenco di tutte le operazioni a lunga esecuzione

    Per elencare le operazioni a lunga esecuzione, utilizza il comando gcloud firestore operations list. Questo comando elenca le operazioni in corso e completate di recente. Le operazioni vengono elencate per alcuni giorni dopo il completamento:

    gcloud firestore operations list
    

    Controllare lo stato dell'operazione

    Anziché elencare tutte le operazioni a lunga esecuzione, puoi elencare i dettagli di una singola operazione:

    gcloud firestore operations describe operation-name

    Stima del tempo di completamento

    Durante l'esecuzione dell'operazione, controlla il valore del campo state per lo stato complessivo dell'operazione.

    Una richiesta relativa allo stato di un'operazione a lunga esecuzione restituisce anche le metriche workEstimated e workCompleted. Queste metriche vengono restituite per il numero di documenti. workEstimated mostra il numero totale stimato di documenti che verrà elaborato da un'operazione. workCompleted mostra il numero di documenti elaborati finora. Al termine dell'operazione,workCompleted riflette il numero totale di documenti effettivamente elaborati, che potrebbe essere diverso dal valore di workEstimated.

    Dividi workCompleted per workEstimated per una stima approssimativa dei progressi. L' stima potrebbe non essere precisa perché dipende dalla raccolta delle statistiche con ritardo.

    Ad esempio, di seguito è riportato lo stato di avanzamento di una compilazione dell'indice:

    {
      "operations": [
        {
          "name": "projects/project-id/operations/AyAyMDBiM2U5NTgwZDAtZGIyYi0zYjc0LTIzYWEtZjg1ZGdWFmZWQHEjF0c2Flc3UtcmV4ZWRuaS1uaW1kYRUKSBI",
          "metadata": {
            "@type": "type.googleapis.com/google.firestore.admin.v1.IndexOperationMetadata",
            "common": {
              "operationType": "CREATE_INDEX",
              "startTime": "2020-06-23T16:52:25.697539Z",
              "state": "PROCESSING"
            },
            "progressDocuments": {
              "workCompleted": "219327",
              "workEstimated": "2198182"
            }
           },
        },
        ...
    

    Al termine di un'operazione, la descrizione dell'operazione conterrà "done": true. Consulta il valore del campo state per il risultato dell'operazione. Se il campo done non è impostato nella risposta, il suo valore è false. Non fare affidamento sull'esistenza del valore done per le operazioni in corso.

    Errori di creazione dell'indice

    Potresti riscontrare errori di creazione dell'indice durante la gestione degli indici compositi e delle esenzioni per gli indici a un solo campo. Un'operazione di indicizzazione può non riuscire se Firestore riscontra un problema con i dati che sta indicizzando. In genere, significa che hai raggiunto un limite di indicizzazione. Ad esempio, l'operazione potrebbe aver raggiunto il numero massimo di voci dell'indice per documento.

    Se la creazione dell'indice non riesce, nella console viene visualizzato il messaggio di errore. Dopo aver verificato di non aver raggiunto i limiti dell'indice, riprova a eseguire l'operazione di indicizzazione.