Réduire les coûts d'index avec les champs de mappage

Cette page explique comment utiliser un champ de mappage pour gérer les paramètres d'index d'un groupe de sous-champs.

Il est recommandé de supprimer les index inutilisés afin de réduire les coûts de stockage et d'améliorer les performances en écriture. Par défaut, Firestore crée un index à champ unique pour chaque champ d'un document. Vous pouvez contrôler l'indexation à champ unique en définissant des exceptions d'index, mais dans la limite de 200 exceptions d'index à champ unique par base de données. Il est possible d'atteindre cette limite avant de désactiver tous les index à champ unique non utilisés.

Vous pouvez éviter d'atteindre le nombre maximal d'exceptions en regroupant les champs de document avec les mêmes exigences d'index que celles d'un champ de mappage. Vous pouvez ensuite appliquer une exception d'index au champ de mappage, et la même exception s'applique aux sous-champs du mappage.

Solution : utiliser les champs de mappage pour faciliter la gestion des index

Imaginons une application qui dépend d'une collection de documents game_event. Examinons les deux modèles de données suivants :

Champs de document de premier niveau

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!',
});

Champ de mappage et sous-champs

Dans ce modèle de données, tous les champs de document deviennent des sous-champs du champ 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!',
  }
});

Supposons que cette application interroge toujours les documents game_event en fonction de user_id et de timestamp, ou de team_id et de timestamp. Exemple :

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');

Remarques concernant cette application :

  • L'application dépend des index composites pour details.user_id, timestamp et details.team_id, timestamp.
  • L'application n'utilise pas les index à champ unique pour timestamp, user_id, team_id, event_type ou display_text.

Sur la base de ces exigences d'index, il est judicieux de désactiver les index à champ unique pour timestamp, user_id, team_id, event_type ou display_text. Comparez maintenant les exceptions requises pour les deux modèles de données.

Désactiver les index pour les champs de premier niveau

Pour désactiver les index à champ unique dans un modèle de données comportant des champs de premier niveau, vous devez définir une exception pour chaque champ. Le nombre d'exceptions augmente de cinq chiffres. Si vous ajoutez un nouveau champ à votre modèle de données, vous devez définir une autre exception pour désactiver son index à champ unique.

Désactiver les index pour les sous-champs

Pour désactiver les index à champ unique pour un modèle de données comportant un mappage et des sous-champs, vous pouvez définir une seule exception pour le champ de mappage. Une exception sur un champ de mappage applique les mêmes paramètres d'indexation aux sous-champs du mappage. Si vous ajoutez un nouveau sous-champ au champ details, l'exception désactive automatiquement l'index à champ unique du nouveau sous-champ.

Par exemple, à l'aide de la CLI Firebase, ajoutez cette exception d'index à votre fichier firestore.indexes.json pour désactiver les index à champ unique de la collection game_events :

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

Si vous avez besoin ultérieurement d'un index à champ unique pour l'un des sous-champs, vous pouvez remplacer le paramètre d'index du champ de mappage par une exception. Une exception sur un sous-champ ignore les paramètres d'index hérités de ce sous-champ. Exemple :

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

Quand utiliser cette approche

Dans l'exemple ci-dessus, le mappage et les sous-champs ont réduit le nombre d'exceptions de cinq à une. Imaginons, cependant, un modèle de données de document similaire comportant 200 champs. Cette approche réduit le nombre d'exceptions de 200 à 1.

Vous devez envisager d'utiliser une approche incluant un champ de mappage et des sous-champs lorsque votre modèle de données de document contient plusieurs champs avec des index à champ unique non utilisés. Cette approche est particulièrement utile pour les documents comportant de nombreux champs.