Riduzione dei costi di indice con i campi mappa

In questa pagina viene descritto come utilizzare un campo mappa per gestire le impostazioni dell'indice di un gruppo di sottocampi.

Come best practice, devi rimuovere gli indici inutilizzati per ridurre i costi di archiviazione e migliorare le prestazioni di scrittura. Per impostazione predefinita, Firestore crea un indice a campo singolo per ogni campo in un documento. Puoi controllare l'indicizzazione a campo singolo definendo le esenzioni dell'indice, ma con un massimo di 200 esenzioni dell'indice a campo singolo per database. È possibile raggiungere questo limite prima di disattivare tutti gli indici a campo singolo non utilizzati.

Per evitare di raggiungere il limite di esenzione, raggruppa i campi dei documenti con gli stessi requisiti di indicizzazione in un campo mappa. Successivamente, puoi applicare un'esenzione indice al campo della mappa e la stessa esenzione viene applicata ai sottocampi della mappa.

Soluzione: usa i campi mappa per gestire gli indici

Immagina un'app che dipende da una raccolta di documenti game_event. Considera i seguenti due modelli di dati:

Campi del documento di primo livello

Node.js
db.collection('game_events').doc().set({
   timestamp: Firestore.FieldValue.serverTimestamp(),
   user_id: 'huDIl8H88kFAFAdcHayf',
   team_id: '6Q5BhBESeTPk8LT0O59I',
   event_type: 'rare_item_drop',
   display_text: 'You found a rare item!',
});

Campo mappa e sottocampi

In questo modello di dati, tutti i campi del documento diventano sottocampi del campo details:

Node.js
db.collection('game_events').doc().set({
  details: {
    timestamp: Firestore.FieldValue.serverTimestamp(),
    user_id: 'huDIl8H88kFAFAdcHayf',
    team_id: '6Q5BhBESeTPk8LT0O59I',
    event_type: 'rare_item_drop',
    display_text: 'You found a rare item!',
  }
});

Supponiamo che questa app esegua sempre query su game_event documenti in base a user_id e timestamp o a team_id e timestamp. Ad esempio:

Node.js
let query_user_events = db.collection('game_events')
                          .where('details.user_id', '==', 'huDIl8H88kFAFAdcHayf')
                          .orderBy('details.timestamp');

let query_team_events = db.collection('game_events')
                          .where('details.team_id', '==', '6Q5BhBESeTPk8LT0O59I')
                          .orderBy('details.timestamp');

Tieni presente i seguenti aspetti relativi a questa app:

  • L'app dipende dagli indici composti di details.user_id, timestamp e details.team_id, timestamp.
  • L'app non utilizza gli indici a campo singolo per timestamp, user_id, team_id, event_type o display_text.

Sulla base di questi requisiti di indice, è consigliabile disattivare gli indici a campo singolo per timestamp, user_id, team_id, event_type o display_text. Ora confronta le esenzioni richieste per i due modelli di dati.

Disabilitazione degli indici per i campi di primo livello

Per disattivare gli indici a campo singolo in un modello di dati di primo livello, devi definire un'esenzione per ogni campo. Il conteggio delle esenzioni aumenta di cinque e, se aggiungi un nuovo campo al modello dei dati, devi definire un'altra esenzione per disattivare l'indice dei singoli campi.

Disabilitazione degli indici per i sottocampi

Per disattivare gli indici a campo singolo per un modello di dati di mappa e sottocampi, puoi definire un'unica esenzione per il campo della mappa. Un'esenzione su un campo della mappa applica le stesse impostazioni di indicizzazione ai sottocampi della mappa. Se aggiungi un nuovo sottocampo al campo details, l'esenzione disabilita automaticamente l'indice a campo singolo del nuovo sottocampo.

Ad esempio, con l'interfaccia a riga di comando di Firebase, aggiungi questa esenzione di indice al file firestore.indexes.json per disattivare gli indici a campo singolo per la raccolta game_events:

{
    "collectionGroup": "game_events",
    "fieldPath": "details",
    "indexes": []
},

Se in un secondo momento richiedi un indice a campo singolo per uno dei sottocampi, puoi sostituire l'impostazione dell'indice del campo mappa con un'esenzione. Un'esenzione su un sottocampo sostituisce le impostazioni indice indicizzate dei campi secondari. Ad esempio:

{
    "collectionGroup": "game_events",
    "fieldPath": "details.event_type",
    "indexes": [
      {
        "order": "ASCENDING",
        "queryScope": "COLLECTION"
      },
    ]
},

Quando utilizzare questo approccio

Nell'esempio precedente, l'approccio alla mappa e ai sottocampi ha ridotto il numero di esenzioni da cinque a uno. Immagina, tuttavia, un modello di dati di documento simile con duecento campi. Questo approccio riduce il numero di esenzioni da 200 a 1.

Ti consigliamo di utilizzare un approccio alla mappa e ai sottocampi quando il modello di dati del documento contiene più campi con indici a campo singolo non utilizzati. In particolare, dovresti prendere in considerazione questo approccio per i documenti che includono molti campi.