Configuração de índice

O Firestore no modo Datastore usa índices para cada consulta feita por seu aplicativo. Esses índices são atualizados sempre que uma entidade muda. Dessa forma, os resultados podem ser retornados rapidamente quando o aplicativo realiza uma consulta. O modo Datastore fornece índices integrados automaticamente, mas precisa determinar com antecedência quais índices compostos o aplicativo necessitará. Especifique quais índices compostos o aplicativo precisa em um arquivo de configuração. O emulador do Datastore pode gerar a configuração de índice do modo Datastore automaticamente conforme você testa seu aplicativo. A ferramenta de linha de comando gcloud fornece comandos para atualizar os índices disponíveis para o banco de dados do modo Datastore de produção.

Requisitos do sistema

Para usar a ferramenta gcloud, você precisa ter instalado o SDK do Google Cloud.

Sobre index.yaml

Todas as consultas do modo Datastore realizadas por um aplicativo precisam de um índice correspondente. Os índices de consultas simples, como as referentes a propriedades únicas, são criados automaticamente. Os índices de consultas complexas precisam ser definidos em um arquivo de configuração chamado index.yaml. Esse arquivo é carregado com o aplicativo para criar índices em um banco de dados do modo Datastore.

O emulador Datastore adiciona automaticamente itens a este arquivo quando o aplicativo tenta executar uma consulta que precisa de um índice que não tem uma entrada apropriada no arquivo de configuração. É possível ajustar os índices ou criar novos manualmente editando o arquivo. O index.yaml está localizado na pasta <project-directory>/WEB-INF/. Por padrão, o diretório de dados que contém WEB-INF/appengine-generated/index.yaml é ~/.config/gcloud/emulators/datastore/. Consulte Diretórios de projeto do emulador Datastore para mais detalhes.

Veja abaixo um exemplo de arquivo index.yaml:

indexes:

- kind: Task
  ancestor: no
  properties:
  - name: done
  - name: priority
    direction: desc

- kind: Task
  properties:
  - name: collaborators
    direction: asc
  - name: created
    direction: desc

- kind: TaskList
  ancestor: yes
  properties:
  - name: percent_complete
    direction: asc
  - name: type
    direction: asc

A sintaxe de index.yaml é o formato YAML. Para obter mais informações sobre essa sintaxe, consulte o site do YAML.

Definições de índice

index.yaml tem um único elemento de lista, denominado indexes. Cada elemento de lista representa um índice do aplicativo.

Um elemento de índice pode ter os seguintes elementos:

kind
O tipo da entidade da consulta. Esse elemento é obrigatório.
properties

Uma lista das propriedades a serem incluídas como colunas do índice, na ordem em que serão classificadas: propriedades usadas em filtros de igualdade primeiro, seguidas de propriedades usadas em filtros de desigualdade, e por fim as ordens de classificação e suas direções.

Cada elemento dessa lista tem os seguintes elementos:

name
O nome da propriedade no modo Datastore.
direction
A direção da classificação, asc para ordem crescente ou desc para decrescente. Isso só é necessário para propriedades usadas nas ordens de classificação da consulta e precisa corresponder à direção usada pela consulta. o padrão é asc.
ancestor

yes caso a consulta tenha uma cláusula ancestral. O padrão é no.

Índices automáticos e manuais

Quando adiciona uma definição de índice gerada a index.yaml, o emulador Datastore faz isso abaixo da linha seguinte, inserindo-a, se necessário:

# AUTOGENERATED

O emulador considera todas as definições de índice abaixo dessa linha como automáticas e pode atualizá-las à medida que o aplicativo realiza consultas.

Todas as definições de índice acima dessa linha são consideradas sob controle manual e não são atualizadas pelo emulador. O emulador só fará alterações abaixo da linha, e somente se o arquivo index.yaml não descrever um índice responsável por uma consulta executada pelo aplicativo. Para assumir o controle de uma definição de índice automática, mova-a para cima dessa linha.

Como atualizar índices

O comando datastore indexes create analisa a configuração de índice do Datastore local (o arquivo index.yaml) e, se a configuração de índice definir um índice ainda não existente no banco de dados do modo Datastore de produção, seu banco de dados criará o novo índice. Consulte o fluxo de trabalho de desenvolvimento usando a ferramenta gcloud para um exemplo de como usar indexes create.

Para criar um índice, o banco de dados precisa configurar o índice e, em seguida, o preencher com dados existentes. A criação do índice é a soma dos tempos de configuração e de preenchimento:

  • A configuração de um índice leva alguns minutos. O tempo de criação mínimo para 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 propriedade pertencerem ao índice, mais demorado será o preenchimento do índice.

Se o aplicativo executar uma consulta que precise de um índice que ainda não esteja totalmente criado, a consulta emitirá uma exceção. Para evitar isso, tome cuidado ao implantar uma nova versão do aplicativo que precise de um índice antes que o novo índice esteja finalizado.

Verifique o status dos índices na página Índices do Console do Cloud.

Como excluir índices não utilizados

Quando você altera ou remove um índice da configuração, o índice original não é excluído automaticamente do banco de dados do modo Datastore. Você tem assim a oportunidade de manter uma versão antiga do aplicativo em execução enquanto os novos índices estão sendo criados, ou de reverter para a versão antiga imediatamente se for detectado algum problema na nova versão.

Quando tiver certeza de que os índices anteriores não são mais necessários, é possível excluí-los usando o comando datastore indexes cleanup. Esse comando exclui todos os índices da instância do modo Datastore de produção não mencionados na versão local de index.yaml. Consulte o fluxo de trabalho de desenvolvimento usando a ferramenta gcloud para um exemplo de como usar indexes cleanup.

Argumentos de linha de comando

Para detalhes sobre argumentos de linha de comando para criar e limpar índices, consulte datastore indexes create e datastore indexes cleanup, respectivamente. Para detalhes sobre argumentos de linha de comando da ferramenta gcloud, consulte a referência da ferramenta gcloud.

Como gerenciar operações de longa duração

As versões de índice são operações de longa duração e podem levar um tempo considerável para serem concluídas.

Depois de iniciar uma criação de índice, o modo Datastore atribui à operação um nome exclusivo. 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 datastore 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

gcloud datastore operations list

rest

Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

  • project-id: ID do projeto

Método HTTP e URL:

GET https://datastore.googleapis.com/v1/projects/project-id/operations

Para enviar a solicitação, expanda uma destas opções:

Veja informações sobre a resposta abaixo.

Por exemplo, uma versão de índice concluída recentemente mostra as seguintes informações:

{
  "operations": [
  {
    "name": "projects/project-id/operations/S01vcFVpSmdBQ0lDDCoDIGRiNTdiZDQNmE4YS0yMTVmNWUzZSQadGx1YWZlZAcSMXRzYWVzdS1yZXhlZG5pLW5pbWRhFQpWEg",
    "done": true,
    "metadata": {
      "@type": "type.googleapis.com/google.datastore.admin.v1.IndexOperationMetadata",
      "common": {
        "endTime": "2020-06-23T16:55:29.923562Z",
        "operationType": "CREATE_INDEX",
        "startTime": "2020-06-23T16:55:10Z",
        "state": "SUCCESSFUL"
      },
      "indexId": "CICAJiUpoMK",
      "progressEntities": {
        "workCompleted": "2193027",
        "workEstimated": "2198182"
      }
    },
    "response": {
      "@type": "type.googleapis.com/google.datastore.admin.v1.Index",
      "ancestor": "NONE",
      "indexId": "CICAJiUpoMK",
      "kind": "Task",
      "projectId": "project-id",
           "properties": [
        {
          "direction": "ASCENDING",
          "name": "priority"
        },
        {
          "direction": "ASCENDING",
          "name": "done"
        },
        {
          "direction": "DESCENDING",
          "name": "created"
        }
      ],
      "state": "READY"
    }
  },
  ]
}

Como descrever uma única 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

Use o comando operations describe para mostrar o status de uma criação de índice.

gcloud datastore operations describe operation-name

rest

Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

  • project-id: ID do projeto

Método HTTP e URL:

GET https://datastore.googleapis.com/v1/projects/project-id/operations

Para enviar a solicitação, expanda uma destas opções:

Veja informações sobre a resposta abaixo.

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 entidades. workEstimated mostra o total estimado de entidades que uma operação processará, com base nas estatísticas do banco de dados. workCompleted mostra o número de entidades processadas até o momento. Após a conclusão da operação, workCompleted reflete o número total de entidades que foram realmente processadas, que podem ser diferentes 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.datastore.admin.v1.IndexOperationMetadata",
        "common": {
          "operationType": "CREATE_INDEX",
          "startTime": "2020-06-23T16:52:25.697539Z",
          "state": "PROCESSING"
        },
        "progressEntities": {
          "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.