Gestisci indici

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

Creare un indice mancante tramite un messaggio di errore

Se tenti di eseguire una query composta da una clausola Range che non esegue la mappatura a un indice esistente. ricevi un messaggio di errore. Il messaggio di errore include un link diretto per creare l'indice mancante nella console Firebase.

Segui il collegamento generato alla console Firebase, rivedi l'impostazione compilate e fai clic su Crea.

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 della piattaforma Google Cloud, 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 Composito.

  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 composto:

  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 Composito.

  4. Nell'elenco degli indici composti, fai clic sul pulsante Altro relativo all'indice da eliminare. Fai clic su Elimina.

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

Aggiungi un'esenzione dell'indice a campo singolo

Le esenzioni dell'indice a campo singolo consentono di ignorare l'indicizzazione automatica impostazioni 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. Attivazione o disattivazione automatica aggiornato in ordine crescente, decrescente e array-contiene indici a campo singolo 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 di indicizzazione che vuoi applicare a tutti i campi nel gruppo di raccolte.

  4. Fai clic su Salva esenzione.

Elimina 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 vengono ripristinati impostazioni indice automatiche. I campi secondari di una mappa ereditano eventuali esenzioni dall'elemento padre prima di ereditare le impostazioni di indice automatiche.

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. Consulta 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.

Sono supportati entrambi gli indici della modalità Native Firestore e della modalità Datastore.

Indice a campo singolo

Il seguente file di configurazione Terraform di esempio crea un indice a campo singolo nel 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 file di configurazione Terraform di esempio 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.

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"
}
Esegui 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 risorsa google_datastore_index precedente.
  4. Rimuovi la risorsa google_datastore_index precedente dallo stato di Terraform.
  5. Esegui terraform apply per applicare eventuali modifiche.

Di seguito sono riportate istruzioni più dettagliate:

  1. Scrivi un valore google_firestore_index sostitutivo in base alla tua 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 a:

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

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

  7. Una volta che l'output del piano Terraform è soddisfacente, 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 esiste un 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 quindi eseguire il backfill dell'indice 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. La build minima per un indice è di pochi minuti, anche per un database vuoto.

    • Il tempo necessario per il backfill dipende dalla quantità di dati esistenti appartenenti al nuovo indice. La più valori di campo che corrispondono alla definizione dell'indice, più tempo occorre 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 dal prefisso projects/[PROJECT_ID]/databases/(default)/operations/ Ad esempio:

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

    Tuttavia, puoi omettere il prefisso quando specifichi il nome di un'operazione 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 quelle 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, osserva il valore del campo state per conoscere lo stato generale 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 dipendono dall'esistenza del valore done per le operazioni in corso.

    Errori di creazione dell'indice

    Potresti riscontrare errori di creazione degli indici quando gestisci indici composti esenzioni degli indici a campo singolo. Un'operazione di indicizzazione può non riuscire se Firestore riscontra un problema con i dati che sta indicizzando. Più alta di solito, questo significa che limite di indice. Ad esempio, l'operazione potrebbe aver raggiunto il numero massimo di voci dell'indice per documento.

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