Gerenciar índices no Cloud Firestore

O Cloud Firestore garante o alto desempenho das consultas ao exigir um índice de todas elas. Os índices necessários para as consultas mais básicas são criados automaticamente para você. À medida que você usa e testa o aplicativo, o Cloud Firestore gera mensagens de erro para ajudar na criação de outros índices necessários. Nesta página, você aprende a gerenciar índices de campo único, compostos e vetor.

Criar um índice inexistente usando uma mensagem de erro

Se você tentar executar uma consulta composta com uma cláusula de intervalo que não esteja mapeada a um índice atual, um erro será retornado. A mensagem desse erro inclui um link direto para você criar o índice inexistente no Console do Firebase.

Abra o link gerado para o Console do Firebase, revise as informações preenchidas automaticamente e clique em Criar.

Caso um índice vetorial seja necessário, a mensagem de erro vai incluir um comando Google Cloud CLI para criar o índice vetorial ausente. Execute o comando para criar o índice ausente.

Papéis e permissões

Antes de criar um índice no Cloud Firestore, confirme se um dos papéis a seguir foi atribuído:

  • roles/datastore.owner
  • roles/datastore.indexAdmin
  • roles/editor
  • roles/owner

Se você tiver definido papéis personalizados, atribua todas as permissões a seguir para criar índices:

  • datastore.indexes.create
  • datastore.indexes.delete
  • datastore.indexes.get
  • datastore.indexes.list
  • datastore.indexes.update

Usar o Console do Firebase

Para criar um novo índice manualmente no Console do Firebase:

Imagem da
interface de indexação do Firestore no Console do Firebase

  1. Acesse a seção Cloud Firestore do console do Firebase:
  2. Acesse a guia Índices e clique em Adicionar índice.
  3. Insira o nome da coleção e defina por quais campos você quer ordenar o índice.
  4. Clique em Criar.

Os campos de índice precisam obedecer às restrições dos caminhos de campo.

Isso pode levar alguns minutos, dependendo do tamanho da consulta. Após a criação, veja os índices e o status na seção "Índices compostos". Se o processo ainda não foi concluído, uma barra de status de criação é exbida no Console do Firebase.

Remover índices

Para excluir um índice:

  1. Acesse a seção Cloud Firestore do console do Firebase:
  2. Clique na guia Índices.
  3. Passe o mouse sobre o índice desejado e selecione Excluir no menu de contexto.
  4. Clique em Excluir no alerta para confirmar a ação.

Usar a CLI do Firebase

Também é possível implantar índices com a CLI do Firebase. Para começar, execute o comando firebase init firestore no diretório do projeto. Durante a configuração, a Firebase CLI gera um arquivo JSON com os índices padrão no formato correto. Edite o arquivo para adicionar mais índices e faça a implantação usando o comando firebase deploy.

Para implantar apenas índices e regras Cloud Firestore, adicione a flag --only firestore.

Se você fizer edições nos índices usando o Console do Firebase, atualize o arquivo de índices local. Consulte a referência de definição do índice JSON.

Usar o Terraform

Como criar índices no banco de dados

Os bancos de dados Cloud Firestore podem incluir índices de campo único e compostos. É possível editar o arquivo de configuração do Terraform para criar um índice para o banco de dados. Os índices de campo único e compostos usam tipos de recursos do Terraform distintos. (google_firestore_index e google_firestore_field).

Índice de campo único

O exemplo de arquivo de configuração do Terraform a seguir cria um índice de campo único no campo name na coleção chatrooms:

firestore.tf

resource "random_id" "variable"{
  byte_length = 8
}

resource "google_firestore_field" "single-index" {
  project = "project-id"
  database = "database-id"
  collection = "chatrooms_${random_id.variable.hex}"
  field = "name"

  index_config {
    indexes {
        order = "ASCENDING"
        query_scope = "COLLECTION_GROUP"
    }
    indexes {
        array_config = "CONTAINS"
    }
  }

  ttl_config {}
}
  • Substitua project-id pela ID do seu projeto. Os ID do projeto precisam ser exclusivos.
  • Substitua database-id pelo ID do banco de dados.

Índice composto

O exemplo de arquivo de configuração do Terraform a seguir cria um índice composto para uma combinação dos campos name e description na coleção chatrooms:

firestore.tf

resource "google_firestore_index" "composite-index" {
  project = "project-id"
  database = "database-id"

  collection = "chatrooms"

  fields {
    field_path = "name"
    order      = "ASCENDING"
  }

  fields {
    field_path = "description"
    order      = "DESCENDING"
  }

}
  • Substitua project-id pela ID do seu projeto. Os ID do projeto precisam ser exclusivos.
  • Substitua database-id pelo ID do banco de dados.

Índice vetorial

O exemplo de arquivo de configuração do Terraform a seguir cria um índice vetorial no campo embedding na coleção chatrooms:

firestore.tf

resource "google_firestore_index" "vector-index" {
  project = "project-id"
  database = "database-id"
  collection = "chatrooms"

  fields {
    field_path = "__name__"
    order = "ASCENDING"
  }

  fields {
    field_path = "embedding"
    vector_config {
      dimension = 128
      flat {}
    }
  }
}
  • Substitua project-id pela ID do seu projeto. Os ID do projeto precisam ser exclusivos.
  • Substitua database-id pelo ID do banco de dados.

Tempo de criação do índice

Para criar um índice, o Cloud Firestore precisa configurar o índice e, em seguida, preencher o índice com os dados existentes. O tempo de criação do índice é a soma do tempo de configuração e do tempo de preenchimento:

  • A configuração de um índice leva alguns minutos. O tempo de criação mínimo de um índice é de alguns minutos, mesmo para um banco de dados vazio.

  • O tempo de preenchimento depende da quantidade de dados no índice novo. Quanto mais valores de campo corresponderem à definição do índice, mais demorado será o preenchimento.

As versões de índice são operações de longa duração.

Depois de iniciar um build de índice, o Cloud Firestore atribui um nome exclusivo à operação. Os nomes das operações são prefixados com projects/[PROJECT_ID]/databases/(default)/operations/, por exemplo:

projects/project-id/databases/(default)/operations/ASA1MTAwNDQxNAgadGx1YWZlZAcSeWx0aGdpbi1zYm9qLW5pbWRhEgopEg

No entanto, é possível deixar de fora o prefixo ao especificar um nome de operação para o comando describe.

Como listar todas as operações de longa duração

Para listar operações de longa duração, use o comando gcloud firestore operations list. Esse comando lista as operações contínuas e as concluídas recentemente. As operações são listadas por alguns dias após a conclusão:

gcloud firestore operations list

Verificar o status da operação

Em vez de listar todas as operações de longa duração, é possível listar os detalhes de uma única operação:

gcloud firestore operations describe operation-name

Como estimar o tempo de conclusão

Conforme sua operação é executada, consulte o valor do campo state para o status geral da operação.

Uma solicitação para o status de uma operação de longa duração também retorna as métricas workEstimated e workCompleted. Essas métricas são retornadas para o número de documentos. workEstimated mostra o número total estimado de documentos que uma operação processará. workCompleted mostra o número de documentos processados até o momento. Após a conclusão da operação, workCompleted reflete o número total de documentos que foram realmente processados, o que pode ser diferente do valor de workEstimated.

Divida workCompleted por workEstimated para ter uma estimativa aproximada do andamento. A estimativa pode ser imprecisa porque depende da coleção de estatísticas em atraso.

Por exemplo, veja o status do progresso de uma criação de índice:

{
  "operations": [
    {
      "name": "projects/project-id/operations/AyAyMDBiM2U5NTgwZDAtZGIyYi0zYjc0LTIzYWEtZjg1ZGdWFmZWQHEjF0c2Flc3UtcmV4ZWRuaS1uaW1kYRUKSBI",
      "metadata": {
        "@type": "type.googleapis.com/google.firestore.admin.v1.IndexOperationMetadata",
        "common": {
          "operationType": "CREATE_INDEX",
          "startTime": "2020-06-23T16:52:25.697539Z",
          "state": "PROCESSING"
        },
        "progressDocuments": {
          "workCompleted": "219327",
          "workEstimated": "2198182"
        }
       },
    },
    ...

Quando uma operação for concluída, a descrição da operação conterá "done": true. Veja o valor do campo state para o resultado da operação. Se o campo done não for definido na resposta, seu valor será false. Não dependa da existência do valor done para operações em andamento.

Erros na criação do índice

Talvez você encontre erros na criação ao gerenciar índices compostos e isenções de índices de campo único. A indexação pode falhar se o Cloud Firestore encontrar um problema com os dados usados nessa operação. Isso costuma significar que você atingiu um limite de índice. Por exemplo, a operação pode ter atingido o número máximo de entradas de índice por documento.

Se a criação do índice falhar, você verá a mensagem de erro no console. Verifique se você atingiu algum limite de índice. Depois, tente novamente a operação de indexação.