Panoramica dell'indice

Questa sezione descrive l'indicizzazione per la versione Firestore Enterprise. Firestore Enterprise edition non crea indici per impostazione predefinita. Per ridurre i costi e migliorare le prestazioni del database, crea indici per le query di uso comune.

Gli indici hanno un impatto significativo sulle prestazioni di un database. Se esiste un indice per una query, il database può restituire i risultati in modo efficiente riducendo la quantità di dati da analizzare e il lavoro necessario per ordinare i risultati. Tuttavia, le voci dell'indice aumentano i costi di archiviazione e la quantità di lavoro svolto durante un'operazione di scrittura sui campi indicizzati.

Definizione e struttura dell'indice

Un indice è costituito da:

  • un ID raccolta
  • un elenco di campi nella raccolta specificata
  • una modalità di indicizzazione, crescente, decrescente o array-contains, per ogni campo

Un indice può anche abilitare le opzioni sparse o unique.

Ordinamento degli indici

L'ordine e la direzione di ordinamento di ogni campo definiscono in modo univoco l'indice. Ad esempio, i seguenti indici sono due indici distinti e non intercambiabili:

Raccolta Campi
città country (ascending), population (descending)
città popolazione (ordine decrescente), paese (ordine crescente),

Quando crei un indice per supportare una query, includi i campi nello stesso ordine della query.

Densità dell'indice

Per impostazione predefinita, le voci dell'indice memorizzano i dati di tutti i documenti di una raccolta. Questo è noto come indice non sparso. Verrà aggiunta una voce di indice per un documento indipendentemente dal fatto che il documento contenga o meno uno dei campi specificati nell'indice. I campi inesistenti vengono trattati come se avessero un valore NULL durante la generazione delle voci dell'indice. Per modificare questo comportamento, puoi definire l'indice come indice sparse.

Indici sparsi

Un indice sparso indicizza solo i documenti nella raccolta che contengono un valore (incluso null) per almeno uno dei campi indicizzati. Un indice sparse riduce i costi di archiviazione e può migliorare le prestazioni.

Indici array-contains

Per ottimizzare le prestazioni delle query quando esegui una query su un campo array utilizzando array-contains o array-contains-any, puoi indicizzare il campo in modalità array-contains. Un indice può avere al massimo un campo in modalità array-contains.

Indicizzando un campo array in modalità array-contains, il motore di query può individuare rapidamente i documenti contenenti valori di array specifici. Senza un indice, le query controllano i valori dell'array eseguendo un'analisi completa della raccolta, il che aumenta le latenze delle query e i costi di lettura man mano che le dimensioni della raccolta aumentano.

Per indicizzare un campo array, il campo deve soddisfare il seguente requisito:

  • Requisito di array non vuoto: una voce di indice viene creata solo se il campo dell'array esiste nel documento ed è un array non vuoto. I documenti con campi mancanti, non array o array vuoti non vengono indicizzati.

Relazione tra densità e indici array-contains

Per gli indici che includono un campo array-contains, le regole di densità dell'indice si applicano solo ai campi indicizzati ordinati. Se il requisito dell'array non vuoto è soddisfatto, le regole di densità si applicano ai restanti campi indicizzati ordinati nell'indice:

  • Indice non sparse (DENSE): viene generata una voce di indice per il documento. Eventuali campi indicizzati ordinati mancanti nell'indice vengono archiviati come null nella voce dell'indice.
  • Indice sparso (SPARSE): viene generata una voce di indice solo se nel documento esiste almeno uno dei campi indicizzati ordinati.

Esempio: generazione di voci di indice

Considera l'indice users (tags[*], status ASC):

Documento NON-SPARSE indice SPARSE indice
{
  tags: ["news"],
  status: "active"
}
Indicizzato:
• (tag: "news", stato: "active")
Indicizzata:
• (tag: "news", stato: "active")
{
  tags: ["news", "sports"],
  status: "active"
}
Indicizzato:
• (tag: "news", stato: "active")
• (tag: "sports", stato: "active")
Indicizzato:
• (tag: "news", stato: "active")
• (tag: "sports", stato: "active")
{
  tags: ["news", "news"],
  status: "active"
}
Indicizzato:
• (tag: "news", stato: "active") (deduplicato)
Indicizzato:
• (tag: "news", stato: "active") (deduplicato)
{
  tags: [null],
  status: "active"
}
Indicizzata:
• (tag: null, stato: "active")
Indicizzata:
• (tag: null, stato: "active")
{
  tags: ["news"]
}
Indicizzato:
• (tag: "news", stato: null)
Non indicizzato (campo status mancante)
{
  tags: "news",
  status: "active"
}
Non indicizzato (il campo non è un array) Non indicizzato (il campo non è un array)
{
  tags: null,
  status: "active"
}
Non indicizzato (il campo non è un array) Non indicizzato (il campo non è un array)
{
  status: "active"
}
Non indicizzato (campo tags mancante) Non indicizzato (campo tags mancante)
{
  tags: [],
  status: "active"
}
Non indicizzato (array vuoto) Non indicizzato (array vuoto)

Esempio di query

Web
// Query for users where 'tags' contains 'news' and 'status' is 'active'
const query = db.collection("users")
  .where("tags", "array-contains", "news")
  .where("status", "==", "active");

// Documents returned by the query:
// [
//   {
//     "id": "alice",
//     "tags": ["news", "tech"],
//     "status": "active"
//   }
// ]

Indici unici

Imposta l'opzione Indice unico per applicare valori unici per i campi indicizzati. Per gli indici su più campi, ogni combinazione di valori deve essere univoca nell'indice. Il database rifiuta qualsiasi operazione di aggiornamento e inserimento che tenta di creare voci di indice con valori duplicati. Se i dati dei campi indicizzati contengono valori duplicati e tenti di creare un indice univoco, la creazione dell'indice non va a buon fine e viene visualizzato un messaggio di errore nei dettagli dell'operazione.

Campi assenti in un indice univoco

Se inserisci un documento con campi mancanti per l'indice univoco, l'indice imposta i valori null per i campi mancanti. La voce dell'indice risultante deve essere univoca, altrimenti l'operazione non va a buon fine.

Ad esempio, con questo indice:

Raccolta Campi indicizzati Ambito di query
città nome (ordine crescente) Raccolta

Se aggiungi il documento {"abbreviation": "LA"} alla raccolta, l'indice univoco crea una voce con name impostato su null. Se poi provi ad aggiungere il documento {"abbreviation": "NYC"}, l'operazione non riesce perché la voce risultante per l'indice univoco è la stessa.

Lo stesso comportamento si applica agli indici univoci con più campi. Durante la creazione o l'aggiornamento di un documento, i campi indicizzati mancanti vengono impostati su null e la voce di indice risultante deve essere univoca nell'indice.

Indici univoci sui valori degli array

Un indice array-contains univoco impedisce la presenza di documenti con elementi di array sovrapposti.

Questo tipo di indice non impone che un array abbia valori univoci all'interno di un singolo documento.

Ad esempio, con un indice univoco su un campo denominato tags:

Il seguente documento, doc1, è valido per l'inserimento:

{
  "tags": [ "news", "tech", "news", "music" ]
}

L'indice consente valori duplicati ("news") all'interno dello stesso array di un singolo documento.

Se provi a inserire un secondo documento, doc2, con un elemento duplicato, l'operazione non va a buon fine:

{
  "tags": [ "sports", "music" ]
}

L'operazione non riesce perché "music" è già presente nell'array di doc1 e mappato nell'indice.

Se devi assicurarti che gli elementi all'interno dello stesso array in un singolo documento siano univoci, gestisci questa operazione nella logica dell'applicazione.

Array vuoti, campi mancanti e valori nulli

In genere, i campi mancanti in un indice univoco vengono trattati come null e devono essere univoci in tutti i documenti (consulta Campi assenti in un indice univoco). Tuttavia, per gli indici univoci sui campi di array:

  • Array vuoti, campi mancanti e valori null autonomi: se il campo dell'array è vuoto, manca completamente o contiene un valore null autonomo (non all'interno di un array), non vengono generate chiavi di indice per il documento. Pertanto, più documenti possono avere campi vuoti o valori null autonomi senza attivare errori di chiave duplicata.
  • Elementi nulli all'interno di un array: se l'array contiene un valore null come elemento (ad esempio, ["news", null]), l'elemento null viene indicizzato. Qualsiasi documento successivo contenente un elemento null nel campo dell'array indicizzato non andrà a buon fine con un errore di chiave duplicata.

Risolvere i problemi relativi alla creazione dell'indice

Durante la gestione degli indici, potresti riscontrare errori di creazione degli indici. Un'operazione di indicizzazione può non riuscire se il database riscontra un problema con i dati. Le operazioni di indicizzazione possono non riuscire per i seguenti motivi:

  • 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 va a buon fine, viene visualizzato un messaggio di errore. Se non hai raggiunto un limite di indici, riprova l'operazione di indicizzazione.
  • Hai impostato l'opzione di indice univoco e i dati dei campi indicizzati creerebbero voci di indice duplicate. Per procedere, rimuovi le combinazioni di valori duplicate dai dati.

Passaggi successivi

Scopri come creare e gestire gli indici.