Como reduzir os custos de índice com campos de mapa

Esta página descreve como usar um campo de mapa para gerenciar configurações de índice de um grupo de subcampos.

Recomendamos remover índices não utilizados para reduzir os custos de armazenamento e melhorar o desempenho de gravação. Por padrão, o Firestore cria um índice de campo único para cada campo em um documento. É possível controlar a indexação de campo único definindo isenções de índice, mas com um máximo de 200 isenções de índice de campo único por banco de dados. É possível atingir esse limite antes de desativar todos os índices não utilizados.

Você pode evitar atingir o limite de isenção agrupando campos de documentos com os mesmos requisitos de índice em um campo do mapa. Em seguida, é possível aplicar uma isenção de índice ao campo de mapa, e a mesma isenção se aplica aos subcampos.

Solução: usar campos de mapa para ajudar a gerenciar índices

Imagine um app que depende de uma coleção de documentos game_event. Considere os dois modelos de dados a seguir:

Campos de documento de nível 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 do mapa e subcampos

Neste modelo de dados, todos os campos do documento se tornam subcampos do 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!',
  }
});

Suponha que esse aplicativo sempre consulte documentos game_event com base em user_id e timestamp ou team_id e timestamp. Exemplo:

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

Considere as seguintes informações sobre o app:

  • O aplicativo depende dos índices compostos para details.user_id, timestamp e details.team_id, timestamp.
  • O app não usa os índices de campo único para timestamp, user_id, team_id, event_type ou display_text.

Com base nesses requisitos de índice, é recomendável desativar os índices de campo único para timestamp, user_id, team_id, event_type ou display_text. Agora, compare as isenções obrigatórias para os dois modelos de dados.

Como desativar índices em campos de nível superior

Para desativar os índices de campo único em um modelo de dados de campos de nível superior, é necessário definir uma isenção para cada campo. Sua contagem de isenção aumenta em cinco e, se você adicionar um novo campo ao modelo de dados, precisará definir outra isenção para desativar o índice de campo único.

Como desativar índices em subcampos

Para desativar os índices de campo único para um modelo de dados de mapa e subcampos, defina uma única isenção para o campo de mapa. Uma isenção em um campo do mapa aplica as mesmas configurações de indexação aos subcampos do mapa. Se você adicionar um novo subcampo ao campo details, a isenção desativará automaticamente o índice de campo único do novo subcampo.

Por exemplo, usando a CLI do Firebase, adicione essa isenção de índice ao arquivo firestore.indexes.json para desativar os índices de campo único da coleção game_events:

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

Se você precisar mais tarde de um índice de campo único para um dos subcampos, substitua a configuração de índice do campo do mapa com uma isenção. Uma isenção em um subcampo modifica as configurações de índice herdadas desse subcampo. Exemplo:

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

Quando usar essa abordagem

No exemplo acima, a abordagem do mapa e dos subcampos reduziu o número de isenções de cinco para um. Imagine, no entanto, um modelo de dados de documentos semelhante com duzentos campos. Essa abordagem reduz o número de isenções de 200 a 1.

Pense em usar um campo de mapa e uma abordagem de subcampos quando seu modelo de dados do documento contiver vários campos com índices de campo único não utilizados. Considere essa abordagem especialmente em documentos com muitos campos.