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 et de réduire les coûts de stockage ainsi que 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 avec un maximum de 200 exceptions d'index à champ unique par base de données. Il est possible d'atteindre cette limite avant de désactiver tous vos index à champ unique inutilisés.

Vous pouvez éviter d'atteindre la limite d'exception en regroupant les champs de document ayant les mêmes exigences d'index sous un champ de mappage. Vous pouvez ensuite appliquer une exception d'index au champ de carte, et cette exception s'applique également aux sous-champs de la carte.

Solution: utiliser des champs de mappage pour gérer les index

Imaginez une application qui repose sur une collection de documents game_event. Prenons l'exemple des 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!',
});

Mapper le champ et les 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 basés sur user_id et timestamp, ou team_id et 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');

Notez les points suivants concernant cette application:

  • L'application dépend des index composites de 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.

Compte tenu de ces exigences d'indexation, il est recommandé de désactiver les index à champ unique pour timestamp, user_id, team_id, event_type ou display_text. À présent, comparez 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 de champ de premier niveau, vous devez définir une exception pour chaque champ. Le nombre d'exceptions augmente de cinq fois. Si vous ajoutez un champ à votre modèle de données, vous devez définir une autre exception pour désactiver son index à champ unique.

Désactiver des index pour les sous-champs

Pour désactiver les index à champ unique pour un modèle de données de carte et de sous-champs, vous pouvez définir une exception unique pour le champ de carte. Une exception sur un champ de carte applique les mêmes paramètres d'indexation aux sous-champs de la carte. Si vous ajoutez un nouveau sous-champ au champ details, l'exception désactive automatiquement le nouvel index à champ unique du 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 pour 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 remplace 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, la carte et les sous-champs ont réduit le nombre d'exceptions de cinq à un. Toutefois, imaginons qu'un modèle de données de document similaire comporte deux cents champs. Cette approche réduit le nombre d'exceptions de 200 à 1.

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