Faça a gestão dos índices

O Firestore garante o desempenho das consultas exigindo um índice para cada consulta. Os índices necessários para as consultas mais básicas são criados automaticamente para si. À medida que usa e testa a sua app, o Cloud Firestore gera mensagens de erro que ajudam a criar índices adicionais de que a sua app precisa. Esta página descreve como gerir os seus índices de campo único, compostos e [vetoriais][vector].

Crie um índice em falta através de uma mensagem de erro

Se tentar uma consulta composta com uma cláusula de intervalo que não seja mapeada para um índice existente, recebe um erro. A mensagem de erro inclui um link direto para criar o índice em falta na consola do Firebase.

Siga o link gerado para a consola do Firebase, reveja as informações preenchidas automaticamente e clique em Criar.

No caso de ser necessário um índice vetorial, a mensagem de erro inclui um comando da CLI gcloud para criar o índice vetorial em falta. Execute o comando para criar o índice em falta.

Funções e permissões

Antes de poder criar um índice no Firestore, certifique-se de que lhe foi atribuída uma das seguintes funções:

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

Se tiver definido funções personalizadas, atribua todas as seguintes autorizações para criar índices:

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

Use a Google Cloud Platform Console

Na Google Cloud Platform Console, pode gerir isenções de indexação de campo único e índices compostos.

Crie um índice composto

Para criar manualmente um novo índice composto a partir da consola da GCP:

  1. Na Google Cloud consola, aceda à página Bases de dados.

    Aceda a Bases de dados

  2. Selecione a base de dados necessária na lista de bases de dados.

  3. No menu de navegação, clique em Índices e, de seguida, clique no separador Composto.

  4. Clique em Criar índice.

  5. Introduza um ID da coleção. Adicione os nomes dos campos que quer indexar e um modo de índice para cada campo. Clique em Guardar índice.

O novo índice é apresentado na lista de índices compostos e o Firestore começa a criar o índice. Quando o índice estiver criado, é apresentada uma marca de verificação verde junto ao índice.

Elimine um índice composto

Para eliminar um índice composto:

  1. Na Google Cloud consola, aceda à página Bases de dados.

    Aceda a Bases de dados

  2. Selecione a base de dados necessária na lista de bases de dados.

  3. No menu de navegação, clique em Índices e, de seguida, clique no separador Composto.

  4. Na lista dos seus índices compostos, clique no botão Mais para o índice que quer eliminar. Clique em Eliminar.

  5. Clique em Eliminar índice no alerta para confirmar que quer eliminar este índice.

Adicione uma isenção de índice de campo único

As isenções de índice de campo único permitem substituir as definições de índice automáticas para campos específicos numa coleção. Pode adicionar uma isenção de campo único a partir da consola:

  1. Na Google Cloud consola, aceda à página Bases de dados.

    Aceda a Bases de dados

  2. Selecione a base de dados necessária na lista de bases de dados.

  3. No menu de navegação, clique em Índices e, de seguida, clique no separador Campo único.

  4. Clique em Adicionar exceção.

  5. Introduza um ID da coleção e um caminho do campo.

  6. Selecione novas definições de indexação para este campo. Ative ou desative os índices de campo único ascendentes, descendentes e array-contains atualizados automaticamente para este campo.

  7. Clique em Guardar isenção.

Adicione uma exceção ao nível da coleção

Para definir uma isenção de índice de campo único que se aplica a todos os campos num ID da coleção:

  1. Clique em Adicionar exceção.
  2. Introduza um ID da coleção para o grupo de coleções e defina o Caminho do campo como *.

    Escolha o campo a isentar

  3. Selecione as isenções de indexação que quer aplicar a todos os campos no grupo de coleções.

  4. Clique em Guardar isenção.

Elimine uma isenção de índice de campo único

Para eliminar uma isenção de índice de campo único, faça o seguinte:

  1. Na Google Cloud consola, aceda à página Bases de dados.

    Aceda a Bases de dados

  2. Selecione a base de dados necessária na lista de bases de dados.

  3. No menu de navegação, clique em Índices e, de seguida, clique no separador Campo único.

  4. Na lista de isenções de índice de campo único, clique no botão Mais para a isenção que quer eliminar. Clique em Eliminar.

  5. Clique em Eliminar no alerta para confirmar que quer eliminar esta isenção.

Quando elimina uma isenção de campo único, o campo ou o subcampo especificado usa as definições de indexação herdadas. Os campos de documentos são revertidos para as definições de índice automáticas da base de dados. Os subcampos num mapa herdam todas as isenções nos campos principais antes de herdarem as definições de índice automáticas.

Use a Firebase CLI

Também pode implementar índices com a Firebase CLI. Para começar, execute firebase init firestore no diretório do projeto. Durante a configuração, a Firebase CLI gera um ficheiro JSON com os índices predefinidos no formato correto. Edite o ficheiro para adicionar mais índices e implemente-o com o comando firebase deploy.

Para implementar apenas regras e índices do Firestore, adicione a flag --only firestore.

Se fizer edições aos índices através da consola do Firebase, certifique-se de que também atualiza o ficheiro de índices local. Consulte a referência da definição do índice JSON.

Use o Terraform

Criar índices na base de dados

As bases de dados do Firestore podem incluir índices de campo único e compostos. Pode editar o ficheiro de configuração do Terraform para criar um índice para a sua base de dados. Os índices de campo único e compostos usam tipos de recursos do Terraform distintos (google_firestore_index e google_firestore_field).

São suportados os índices do modo nativo do Firestore e do modo Datastore.

Índice de campo único

O ficheiro de configuração do Terraform de exemplo seguinte 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 pelo ID do seu projeto. Os IDs dos projetos têm de ser exclusivos.
  • Substitua database-id pelo ID da base de dados.

Índice composto

O ficheiro de configuração do Terraform de exemplo seguinte cria um índice composto para uma combinação do campo name e do campo 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 pelo ID do seu projeto. Os IDs dos projetos têm de ser exclusivos.
  • Substitua database-id pelo ID da base de dados.

Índice vetorial

O seguinte ficheiro de configuração do Terraform de exemplo 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 pelo ID do seu projeto. Os IDs dos projetos têm de ser exclusivos.
  • Substitua database-id pelo ID da base de dados.

Índices do modo Datastore

Também pode criar índices do modo Datastore com o Terraform.

datastore.tf

resource "google_firestore_index" "datastore-mode-index" {
  project = "project-id"
  database = "database-id"

  collection = "chatrooms"

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

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

  query_scope = "COLLECTION_GROUP"
  api_scope   = "DATASTORE_MODE_API"
}
Migre de google_datastore_index

O recurso google_datastore_index está obsoleto e vai ficar indisponível na versão 6.0.0 e posteriores do terraform-provider-google.

Se usava anteriormente o recurso google_datastore_index, pode migrar para google_firestore_index. Para fazer a migração, siga estes passos:

  1. Escrever um recurso google_firestore_index equivalente.
  2. Importe o seu índice do modo Datastore existente para o novo recurso.
  3. Remova as referências ao recurso google_datastore_index antigo.
  4. Remova o recurso google_datastore_indexantigo do estado do Terraform.
  5. A executar terraform apply para aplicar as alterações.

Seguem-se instruções mais detalhadas:

  1. Escreva um google_firestore_index de substituição com base no recurso google_datastore_index existente. Consulte as alterações necessárias abaixo.
  2. Determine o caminho do recurso do Firestore do seu índice:

    export INDEX_RESOURCE_PATH=$(echo '"projects/${google_datastore_index.datastore-index-resource-name.project}/databases/(default)/collectionGroups/${google_datastore_index.datastore-index-resource-name.kind}/indexes/${google_datastore_index.datastore-index-resource-name.index_id}"' | terraform console | tr -d '"')
    

    Substitua datastore-index-resource-name pelo nome do Terraform do seu recurso existente.

  3. Importe o seu índice do modo Datastore para o recurso google_firestore_index que criou acima:

    terraform import google_firestore_index.firestore-index-resource-name $INDEX_RESOURCE_PATH
    

    Substitua firestore-index-resource-name pelo nome do Terraform do seu recurso existente.

    Para mais informações sobre a importação de recursos de índice do Firestore, consulte a documentação de referência google_firestore_index.

  4. Elimine o recurso google_datastore_index existente do ficheiro de configuração do Terraform.
  5. Remova o recurso google_datastore_index existente do estado do Terraform:

    terraform state rm google_datastore_index.datastore-index-resource-name
    

    Para mais informações sobre a remoção de recursos, consulte a página do Terraform sobre a remoção de recursos.

  6. Corrida terraform plan. Valide o resultado para confirmar que não está a criar nem a destruir recursos.

    Inspeccione o resultado para garantir que a importação foi concluída com êxito. Se o resultado mostrar alterações a campos, certifique-se de que estas alterações são intencionais. Se o resultado incluir uma linha semelhante a:

    google_firestore_index.firestore-index-resource-name must be replaced
    

    Em seguida, inspecione o ficheiro de configuração do Terraform para ver se existem erros.

  7. Quando estiver satisfeito com o resultado do plano do Terraform, execute o seguinte comando:

    terraform apply
    

  8. Traduza o seu índice

    Para traduzir um recurso google_datastore_index para o recurso google_firestore_index equivalente, copie-o e faça as seguintes alterações:

    • Substituir google_datastore_index por google_firestore_index.
    • Substitua o nome do argumento kind por collection, mas mantenha o valor do argumento igual.
    • Substitua o nome do argumento ancestor por query_scope. Substitua o valor do argumento ALL_ANCESTORS por COLLECTION_RECURSIVE e qualquer outro valor por COLLECTION_GROUP. Se não existir nenhum argumento ancestor, adicione um argumento query_scope com o valor COLLECTION_GROUP.
    • Adicione o argumento api_scope com o valor DATASTORE_MODE_API.
    • Para cada instância de properties, substitua-a por uma instância correspondente de fields. Substitua cada instância de name por field_path e cada instância de direction por order.

    Por exemplo, considere este recurso google_datastore_index:

    datastore.tf

    resource "google_datastore_index" "legacy" {
      kind = "foo"
    
      properties {
        name = "property_a"
        direction = "ASCENDING"
      }
    
      properties {
        name = "property_b"
        direction = "ASCENDING"
      }
    }
    

    O recurso google_firestore_index equivalente seria:

    resource "google_firestore_index" "new" {
      // note: defaults to the provider project
      project = project
    
      // note: defaults to the (default) database
      database = "(default)"
    
      collection = "foo"
    
      api_scope = "DATASTORE_MODE_API"
    
      // since there was no "ancestor" property set above, use COLLECTION_GROUP here
      query_scope = "COLLECTION_GROUP"
    
      fields {
        field_path = "property_a"
        order  = "ASCENDING"
      }
    
      fields {
        field_path = "property_b"
        order = "ASCENDING"
      }
    }
    

    Tempo de criação do índice

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

    • A configuração de um índice demora alguns minutos. O tempo de compilação mínimo para um índice é de alguns minutos, mesmo para uma base de dados vazia.

    • O tempo de preenchimento depende da quantidade de dados existentes que pertencem ao novo índice. Quanto mais valores de campo corresponderem à definição do índice, mais tempo demora a preencher o índice.

    As compilações de índices são operações de longa duração.

    Depois de iniciar uma compilação de índice, o Firestore atribui um nome único à operação. Os nomes das operações têm o prefixo projects/[PROJECT_ID]/databases/(default)/operations/, por exemplo:

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

    No entanto, pode omitir o prefixo quando especificar um nome de operação para o comando describe.

    Listar todas as operações de longa duração

    Para apresentar uma lista de operações de longa duração, use o comando gcloud firestore operations list. Este comando apresenta as operações em curso e concluídas recentemente. As operações são apresentadas durante alguns dias após a conclusão:

    gcloud firestore operations list
    

    Verifique o estado da operação

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

    gcloud firestore operations describe operation-name

    Estimar o tempo de conclusão

    À medida que a operação é executada, veja o valor do campo state para o estado geral da operação.

    Um pedido do estado de uma operação de longa duração também devolve as métricas workEstimated e workCompleted. Estas métricas são devolvidas para o número de documentos. workEstimated mostra o número total estimado de documentos que uma operação vai processar. workCompleted mostra o número de documentos processados até agora. 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 uma estimativa aproximada do progresso. A estimativa pode ser imprecisa porque depende da recolha de estatísticas atrasadas.

    Por exemplo, segue-se o estado de 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 estiver concluída, a descrição da operação contém "done": true. Consulte o valor do campo state para ver o resultado da operação. Se o campo done não estiver definido na resposta, o respetivo valor é false. Não dependa da existência do valor done para operações em curso.

    Erros de criação de índices

    Pode encontrar erros de criação de índices ao gerir índices compostos e isenções de índice de campo único. Uma operação de indexação pode falhar se o Firestore encontrar um problema com os dados que está a indexar. Na maioria dos casos, isto significa que 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, é apresentada a mensagem de erro na consola. Depois de verificar que não está a atingir nenhum limite de índice, tente novamente a operação de indexação.