Reduce los costos de índice con campos de mapa

En esta página se describe cómo usar un campo de mapa para administrar la configuración de índices de un grupo de subcampos.

Una práctica recomendada es quitar los índices que no uses para reducir los costos de almacenamiento y mejorar el rendimiento de escritura. Según la configuración predeterminada, Cloud Firestore compila un índice de campo único para cada campo de un documento. Puedes controlar la indexación de los campos únicos si defines las exenciones de índice, pero solo puedes tener un máximo de 200 exenciones de índices de campo único por base de datos. Es posible que alcances este límite antes de inhabilitar todos los índices de campo único sin usar.

Para evitar este problema, agrupa los campos del documento que tengan los mismos requisitos de índice en un campo de mapa. Luego, puedes aplicar una exención de índice al campo de mapa, que se aplicará a los subcampos del mapa.

Solución: Usa campos de mapas para administrar índices

Imagina que tienes una app que depende de una colección de documentos game_event. Considera los siguientes modelos de datos:

Campos de documentos de nivel superior

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 de mapa y subcampos

En este modelo de datos, todos los campos del documento se convierten en subcampos 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!',
  }
});

Supongamos que esta app siempre consulta documentos de game_event en función del user_id y la timestamp, o del team_id y la timestamp. Por ejemplo:

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

Considera lo siguiente sobre esta app:

  • Depende de los índices compuestos de details.user_id, timestamp y details.team_id, timestamp.
  • No usa los índices de campo único para timestamp, user_id, team_id, event_type ni display_text.

En función de estos requisitos de índice, se recomienda inhabilitar los índices de campo único para timestamp, user_id, team_id, event_type o display_text. Ahora compara las exenciones necesarias para los dos modelos de datos.

Inhabilita índices para campos de nivel superior

Si quieres inhabilitar los índices de campo único en un modelo de datos de campos de nivel superior, debes definir una exención para cada campo. Tu recuento de exenciones aumenta en cinco y, si agregas un campo nuevo al modelo de datos, debes definir otra exención para inhabilitar su índice de campo único.

Inhabilita índices para subcampos

Si quieres inhabilitar los índices de campo único para un mapa y un modelo de datos de subcampos, puedes definir una única exención para el campo de mapa. Esta aplica la misma configuración de indexación a los subcampos del mapa. Si agregas un subcampo nuevo al campo details, la exención inhabilitará automáticamente el índice de campo único del subcampo nuevo.

Por ejemplo, puedes usar Firebase CLI para agregar la exención de índices a tu archivo firestore.indexes.json y, así, inhabilitar los índices de campo único de la colección game_events:

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

Si más adelante necesitas un índice de campo único para uno de los subcampos, puedes anular la configuración de índice del campo de mapa con una exención. La exención en un subcampo anula la configuración de índice heredado de ese subcampo. Por ejemplo:

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

Cuándo debes usar este enfoque

En el ejemplo anterior, el enfoque de mapa y subcampos redujo la cantidad de exenciones de cinco a una. Sin embargo, imagina que tienes un modelo de datos de documento similar con doscientos campos. Este enfoque reduce la cantidad de exenciones de doscientas a una.

Usa un enfoque de campo de mapa y subcampos cuando el modelo de datos de tu documento incluya varios campos con índices de campo único que no se usen. Debes considerar este enfoque especialmente para los documentos con muchos campos.