Configuración de índices compuestos

Firestore en el modo de Datastore usa índices para cada consulta que haga tu aplicación. Estos índices se actualizan cada vez que cambia una entidad, por lo que los resultados se pueden devolver rápidamente cuando la aplicación hace una consulta. El modo Datastore proporciona índices integrados automáticamente, pero necesita saber de antemano qué índices compuestos requerirá la aplicación. En un archivo de configuración, se especifican los índices compuestos que necesita la aplicación. El emulador de Datastore puede generar automáticamente la configuración del índice compuesto del modo Datastore mientras pruebas tu aplicación. La herramienta de línea de comandos gcloud proporciona comandos para actualizar los índices disponibles en tu base de datos en modo Datastore de producción.

Requisitos del sistema

Para usar gcloud CLI, debes haber instalado Google Cloud CLI.

Acerca de index.yaml

Cada consulta en el modo Datastore que realice una aplicación necesita un índice correspondiente. Los índices de consultas sencillas, como las consultas de una sola propiedad, se crean automáticamente. Los índices compuestos de las consultas complejas deben definirse en un archivo de configuración llamado index.yaml. Este archivo se sube con la aplicación para crear índices compuestos en una base de datos en modo Datastore.

El emulador de Datastore añade automáticamente elementos a este archivo cuando la aplicación intenta ejecutar una consulta que necesita un índice compuesto que no tiene una entrada adecuada en el archivo de configuración. Puedes ajustar los índices compuestos o crear otros nuevos manualmente editando el archivo. El archivo index.yaml se encuentra en la carpeta <project-directory>/WEB-INF/. De forma predeterminada, el directorio de datos que contiene WEB-INF/appengine-generated/index.yaml es ~/.config/gcloud/emulators/datastore/. Consulta Directorios de proyectos del emulador de Datastore para obtener más información.

A continuación, se muestra un ejemplo de un archivo 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

La sintaxis de index.yaml es el formato YAML. Para obtener más información sobre esta sintaxis, consulta el sitio web de YAML.

Definiciones de índices compuestos

index.yaml tiene un solo elemento de lista llamado indexes. Cada elemento de la lista representa un índice compuesto de la aplicación.

Un elemento de índice puede contener los siguientes elementos:

kind
El tipo de entidad de la consulta. Este elemento es obligatorio.
properties

Lista de propiedades que se incluirán como columnas del índice compuesto, en el orden en el que se van a ordenar: primero, las propiedades que se usan en los filtros de igualdad; después, la propiedad que se usa en los filtros de desigualdad; y, por último, los órdenes de clasificación y sus direcciones.

Cada elemento de esta lista incluye los siguientes elementos:

name
Nombre de la propiedad en el modo de Datastore.
direction
Orden en que se muestran los resultados. Puede ser asc (ascendente) o desc (descendente). Solo es obligatorio en las propiedades que se usan en los criterios de ordenación de la consulta y debe coincidir con la dirección que usa la consulta. El valor predeterminado es asc.
ancestor

yes si la consulta tiene una cláusula de ancestro. El valor predeterminado es no.

Índices compuestos automáticos y manuales

Cuando el emulador de Datastore añade una definición de índice compuesto generada a index.yaml, lo hace debajo de la siguiente línea, insertándola si es necesario:

# AUTOGENERATED

El emulador considera que todas las definiciones de índice compuesto que se encuentran debajo de esta línea son automáticas y puede actualizar las definiciones que se encuentren debajo de esta línea a medida que la aplicación realice consultas.

Todas las definiciones de índice compuesto que se encuentren por encima de esta línea se considerarán bajo control manual y el emulador no las actualizará. El emulador solo hará cambios por debajo de la línea y solo lo hará si el archivo index.yaml completo no describe un índice compuesto que tenga en cuenta una consulta ejecutada por la aplicación. Para tomar el control de una definición de índice compuesto automático, muévala por encima de esta línea.

Actualizar índices compuestos

El comando datastore indexes create consulta la configuración del índice compuesto local de Datastore (el archivo index.yaml) y, si la configuración del índice compuesto define un índice compuesto que aún no existe en tu base de datos del modo Datastore de producción, tu base de datos crea el nuevo índice compuesto. Consulta el flujo de trabajo de desarrollo con gcloud CLI para ver un ejemplo de cómo usar indexes create.

Para crear un índice compuesto, la base de datos debe configurarlo y, a continuación, rellenarlo con los datos que ya tenga. El tiempo de creación de un índice compuesto es la suma del tiempo de configuración y el tiempo de relleno:

  • Configurar un índice compuesto lleva unos minutos. El tiempo mínimo de creación de un índice compuesto es de unos minutos, incluso en el caso de una base de datos vacía.

  • El tiempo de relleno depende de la cantidad de datos que haya en el nuevo índice compuesto. Cuantos más valores de propiedad pertenezcan al índice compuesto, más tiempo se tardará en rellenarlo.

Si la aplicación realiza una consulta que requiere un índice compuesto que aún no se ha terminado de crear, la consulta genera una excepción. Para evitarlo, debes tener cuidado al implementar una nueva versión de tu aplicación que requiera un índice compuesto antes de que se termine de crear el nuevo índice compuesto.

Puedes consultar el estado de los índices compuestos en la página Índices de la Google Cloud consola.

Eliminar índices compuestos no utilizados

Cuando cambias o quitas un índice compuesto de la configuración de índices compuestos, el índice compuesto original no se elimina automáticamente de tu base de datos en modo Datastore. De esta forma, puedes dejar una versión anterior de la aplicación en ejecución mientras se crean los nuevos índices compuestos o volver a la versión anterior inmediatamente si se detecta un problema con una versión más reciente.

Cuando te asegures de que ya no necesitas los índices compuestos antiguos, puedes eliminarlos con el comando datastore indexes cleanup. Este comando elimina todos los índices compuestos de la instancia del modo de producción de Datastore que no se mencionan en la versión local de index.yaml. Consulta el flujo de trabajo de desarrollo con la herramienta de línea de comandos gcloud para ver un ejemplo de cómo usar indexes cleanup.

Argumentos de línea de comandos

Para obtener información sobre los argumentos de línea de comandos para crear y limpiar índices compuestos, consulta datastore indexes create y datastore indexes cleanup, respectivamente. Para obtener información sobre los argumentos de la línea de comandos de gcloud CLI, consulta la referencia de gcloud CLI.

Gestionar operaciones de larga duración

Las compilaciones de índices compuestos son operaciones de larga duración y pueden tardar bastante en completarse.

Después de iniciar una compilación de índice compuesto, el modo Datastore asigna un nombre único a la operación. Los nombres de las operaciones van precedidos de projects/[PROJECT_ID]/databases/(default)/operations/, por ejemplo:

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

Sin embargo, puede omitir el prefijo al especificar un nombre de operación para el comando describe.

Mostrar todas las operaciones de larga duración

Para enumerar las operaciones de larga duración, usa el comando gcloud datastore operations list. Este comando muestra las operaciones en curso y las que se han completado recientemente. Las operaciones se muestran durante unos días después de completarse:

gcloud

gcloud datastore operations list

rest

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • project-id: tu ID de proyecto

Método HTTP y URL:

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

Para enviar tu solicitud, despliega una de estas opciones:

Consulta la información sobre la respuesta a continuación.

Por ejemplo, una compilación de índice compuesto completada recientemente muestra la siguiente información:

{
  "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"
    }
  },
  ]
}

Describir una sola operación

En lugar de enumerar todas las operaciones de larga duración, puedes consultar los detalles de una sola operación:

gcloud

Usa el comando operations describe para mostrar el estado de una compilación de índice compuesto.

gcloud datastore operations describe operation-name

rest

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • project-id: tu ID de proyecto

Método HTTP y URL:

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

Para enviar tu solicitud, despliega una de estas opciones:

Consulta la información sobre la respuesta a continuación.

Estimar el tiempo de finalización

Mientras se ejecuta la operación, consulta el valor del campo state para ver el estado general de la operación.

Una solicitud del estado de una operación de larga duración también devuelve las métricas workEstimated y workCompleted. Estas métricas se devuelven para el número de entidades. workEstimated muestra el número total estimado de entidades que procesará una operación, en función de las estadísticas de la base de datos. workCompleted muestra el número de entidades procesadas hasta el momento. Una vez completada la operación, workCompleted refleja el número total de entidades que se han procesado, que puede ser diferente del valor de workEstimated.

Divide workCompleted entre workEstimated para obtener una estimación aproximada del progreso. Es posible que la estimación no sea precisa porque depende de la recogida de estadísticas con retraso.

Por ejemplo, este es el estado de progreso de una compilación de índice compuesto:

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

Cuando se complete una operación, la descripción de la operación contendrá "done": true. Consulta el valor del campo state para ver el resultado de la operación. Si el campo done no se define en la respuesta, su valor será false. No dependas de la existencia del valor done para las operaciones en curso.