Gestire gli indici di Standard edition

Il comportamento di indicizzazione dipende dalla versione del database. Questa pagina descrive come gestire gli indici per Firestore Standard. Per Firestore Enterprise Edition, consulta la Panoramica degli indici di Firestore Enterprise Edition.

Firestore Standard Edition garantisce le prestazioni delle query richiedendo un indice per ogni query. Gli indici richiesti per le query più semplici vengono creati automaticamente per te. Man mano che utilizzi e testi la tua app, Firestore Standard Edition genera messaggi di errore che ti aiutano a creare indici aggiuntivi di cui la tua app ha bisogno. Questa pagina descrive come gestire gli indici a campo singolo, compositi e vettoriali.

Creare un indice mancante tramite un messaggio di errore

Se tenti di eseguire una query composta con una clausola di intervallo che non corrisponde a un indice esistente, ricevi 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, rivedi le informazioni compilate automaticamente e fai clic su Crea.

Nel caso in cui sia necessario un indice vettoriale, il messaggio di errore includerà un comando Google Cloud CLI per creare l'indice vettoriale mancante. Esegui il comando per creare l'indice mancante.

Ruoli e autorizzazioni

Prima di poter creare un indice in Firestore Standard, assicurati di disporre di 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 indici:

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

Utilizzare la console Google Cloud

Dalla console 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 composito dalla console GCP:

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

    Vai a Database

  2. Seleziona il database richiesto dall'elenco.

  3. Nel menu di navigazione, fai clic su Indici, quindi 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 compositi e Firestore Standard inizierà a crearlo. Al termine della creazione dell'indice, 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.

  3. Nel menu di navigazione, fai clic su Indici, quindi sulla scheda Composito.

  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 questo indice facendo clic su Elimina indice nell'avviso.

Aggiungere un'esenzione dell'indice a campo singolo

Le esenzioni per gli indici a campo singolo consentono di eseguire l'override delle impostazioni degli indici automatici 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.

  3. Nel menu di navigazione, fai clic su Indici, quindi sulla scheda Singolo campo.

  4. Fai clic su Aggiungi esenzione.

  5. Inserisci un ID raccolta e un percorso del campo.

  6. Seleziona le nuove impostazioni di indicizzazione per questo campo. Attiva o disattiva gli indici a campo singolo in ordine crescente, decrescente e array-contains 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 applichi a tutti i campi in un ID raccolta:

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

    Scegli il campo da esentare

  3. Seleziona le esenzioni dall'indicizzazione che vuoi 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.

  3. Nel menu di navigazione, fai clic su Indici, quindi sulla scheda Singolo campo.

  4. Nell'elenco delle esenzioni dall'indice a un solo 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 campo secondario specificato utilizzerà le impostazioni di indicizzazione ereditate. I campi del documento vengono ripristinati alle impostazioni automatiche dell'indice del database. I campi secondari di una mappa ereditano le esenzioni sui 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, la CLI Firebase genera un file JSON con gli indici predefiniti nel formato corretto. Modifica il file per aggiungere altri indici e implementalo con il comando firebase deploy.

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

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

Utilizza Terraform

Creazione di indici nel database

I database Firestore Standard edition possono includere indici a un solo campo 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 della modalità Native di Firestore sia quelli della modalità Datastore.

Indice a campo singolo

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

Indice vettoriale

Il seguente file di configurazione Terraform di esempio crea un indice vettoriale 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 della 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 versione 6.0.0 e 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 in modalità Datastore esistente 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. Esecuzione di terraform apply per applicare le modifiche.

Di seguito sono riportate istruzioni più dettagliate:

  1. Scrivi un google_firestore_index sostitutivo in base alla risorsa google_datastore_index esistente. Per le modifiche necessarie, vedi di seguito.
  2. Determina il percorso della risorsa Firestore del tuo 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 che hai creato in precedenza:

    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 indice 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 saperne di più sulla rimozione delle risorse, consulta la pagina di Terraform sulla rimozione delle risorse.

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

    Controlla l'output per assicurarti che l'importazione sia stata completata correttamente. Se l'output mostra modifiche ai campi, assicurati che 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 sono stati commessi errori.

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

    terraform apply
    

  8. Tradurre l'indice

    Per convertire 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 alcun argomento ancestor, aggiungi un argomento query_scope con il 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 sarebbe:

    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 creazione dell'indice

    Per creare un indice, Firestore Standard deve configurarlo e poi riempirlo con i dati esistenti. Il tempo di creazione dell'indice è la somma del tempo di configurazione e del tempo di backfill:

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

    • Il tempo necessario per il backfill dipende dalla quantità di dati esistenti che devono essere inclusi nel nuovo indice. Più valori di campo corrispondono alla definizione dell'indice, più tempo ci vuole per eseguire il backfill dell'indice.

    Le build dell'indice sono operazioni a lunga esecuzione.

    Dopo aver avviato la creazione di un indice, Firestore Standard assegna all'operazione un nome univoco. I nomi delle operazioni hanno il prefisso projects/[PROJECT_ID]/databases/(default)/operations/, ad esempio:

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

    Tuttavia, puoi omettere il prefisso quando specifichi un nome di 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 quelle completate di recente. Le operazioni vengono elencate per alcuni giorni dopo il completamento:

    gcloud firestore operations list
    

    Controlla 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

    Mentre l'operazione è in esecuzione, visualizza il valore del campo state per lo stato complessivo dell'operazione.

    Una richiesta dello 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 un'operazione elaborerà. 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. La stima potrebbe essere imprecisa perché dipende dalla raccolta ritardata delle statistiche.

    Ad esempio, ecco lo stato di avanzamento della creazione di un 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. Visualizza 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 degli indici a campo singolo. Un'operazione di indicizzazione può non riuscire se Firestore Standard edition rileva un problema con i dati che sta indicizzando. Nella maggior parte dei casi, questo significa che hai raggiunto un limite di indice. Ad esempio, l'operazione potrebbe aver raggiunto il numero massimo di voci di 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 di indice, riprova l'operazione di indicizzazione.