Riduzione dei costi di indice con i campi mappa

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

Come best practice, devi rimuovere gli indici non utilizzati 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 esenzioni dell'indice, ma con un massimo di 200 esenzioni per 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 del documento con gli stessi requisiti di indice in un campo mappa. Successivamente, puoi applicare un'esenzione per l'indice al campo mappa e la stessa esenzione si applica ai sottocampi della mappa.

Soluzione: utilizza i campi della mappa per gestire gli indici

Immagina un'app che dipende da una raccolta di game_event documenti. 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!',
});

Mappa campo e sottocampi

In questo modello dei dati, tutti i campi dei documenti diventano campi secondari 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 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 quanto segue su questa app:

  • L'app dipende dagli indici composti per 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.

In base a questi requisiti di indicizzazione, è 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 dei dati.

Disattivazione degli indici per i campi di primo livello

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

Disattivazione degli indici per i campi secondari

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

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

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

Se in seguito hai bisogno di un indice a campo singolo per uno dei campi secondari, puoi sostituire l'impostazione relativa all'indice del campo mappa con un'esenzione. Un'esenzione per un sottocampo sostituisce le impostazioni di indice ereditate del sottocampo. Ad esempio:

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

Quando utilizzare questo approccio

Nell'esempio precedente, la mappa e i campi secondari hanno ridotto il numero di esenzioni da cinque a uno. Tuttavia, immaginate un modello dei dati di documenti simile con duecento campi. Questo approccio riduce il numero di esenzioni da 200 a 1.

Ti consigliamo di utilizzare un approccio basato su campi di mappa e sottocampi quando il modello dei dati del documento contiene più campi con indici a campo singolo non utilizzati. Questo approccio deve essere particolarmente utile per i documenti che includono molti campi.