Configuração de índice composto

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 composto 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 CLI gcloud, você precisa ter instalado a Google Cloud CLI.

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 compostos para consultas complexas precisam ser definidos em um arquivo de configuração chamado index.yaml. Esse arquivo é enviado com o aplicativo para criar índices compostos em um banco de dados do modo Datastore.

O emulador do Datastore adiciona automaticamente itens a este arquivo quando o aplicativo tenta executar uma consulta que precisa de um índice composto que não tem uma entrada apropriada no arquivo de configuração. É possível ajustar índices compostos 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 composto

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

Um elemento de índice pode ter os elementos a seguir:

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

Uma lista das propriedades a serem incluídas como colunas do índice composto, na ordem em que serão classificadas: primeiro as propriedades usadas em filtros de igualdade, seguidas de propriedades usadas em filtros de desigualdade e, depois, as ordens de classificação e as 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 compostos automáticos e manuais

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

# AUTOGENERATED

O emulador considera todas as definições de índice composto abaixo desta linha como automáticas e pode atualizar as definições abaixo dela, à medida que o aplicativo faz consultas.

Todas as definições de índice composto 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 composto que se refira a uma consulta executada pelo aplicativo. Para assumir o controle de uma definição de índice composto automática, mova-a para cima dessa linha.

Como atualizar índices compostos

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

Para criar um índice composto, o banco de dados precisa configurá-lo e, em seguida, preencher o índice composto com os dados existentes. A criação de um índice composto é a soma do tempo de configuração e de preenchimento:

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

  • O tempo de preenchimento depende da quantidade de dados no índice composto novo. Quanto mais valores de propriedade pertencerem ao índice composto, mais demorado será o preenchimento do índice composto.

Se o aplicativo executar uma consulta que exija um índice composto 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 composto antes que o novo índice composto seja criado.

Verifique o status dos índices compostos na página Índices do console do Google Cloud.

Como excluir índices compostos não utilizados

Quando você altera ou remove um índice composto da configuração, o índice composto original não é excluído automaticamente do banco de dados do modo Datastore. Isso dá a você a oportunidade de manter uma versão antiga do aplicativo em execução enquanto os novos índices compostos estão sendo criados ou de reverter para a versão antiga imediatamente se um problema for detectado em uma versão mais recente.

Quando tiver certeza de que os índices compostos antigos não são mais necessários, exclua-os usando o comando datastore indexes cleanup. Esse comando exclui todos os índices compostos 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 CLI 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 compostos, consulte datastore indexes create e datastore indexes cleanup, respectivamente. Para saber mais sobre os argumentos de linha de comando da CLI gcloud, consulte a referência da CLI gcloud.

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

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

Depois de iniciar um build de índice composto, o modo Datastore 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 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 composto 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 composto.

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, confira o status do progresso de uma criação de índice composto:

{
  "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.