Gestionar índices
Firestore asegura el rendimiento de las consultas al requerir un índice para cada consulta. Los índices necesarios para las consultas más básicas se crean automáticamente. Mientras usas y pruebas tu aplicación, Cloud Firestore genera mensajes de error que te ayudan a crear los índices adicionales que necesita tu aplicación. En esta página se describe cómo gestionar tus índices de campo único, compuestos y [vector][vector].
Crear un índice que falta a través de un mensaje de error
Si intentas hacer una consulta compuesta con una cláusula de intervalo que no se corresponda con un índice, recibirás un error. El mensaje de error incluye un enlace directo para crear el índice que falta en la consola de Firebase.
Sigue el enlace generado a la consola de Firebase, revisa la información que se ha rellenado automáticamente y haz clic en Crear.
Si se necesita un índice vectorial, el mensaje de error incluirá un comando de la interfaz de línea de comandos de Google Cloud para crear el índice vectorial que falta. Ejecuta el comando para crear el índice que falta.
Roles y permisos
Para poder crear un índice en Firestore, debes tener asignado uno de los siguientes roles:
roles/datastore.owner
roles/datastore.indexAdmin
roles/editor
roles/owner
Si has definido roles personalizados, asigna todos los permisos siguientes para crear índices:
datastore.indexes.create
datastore.indexes.delete
datastore.indexes.get
datastore.indexes.list
datastore.indexes.update
Usar la consola de Google Cloud Platform
Desde la consola de Google Cloud Platform, puede gestionar las exenciones de indexación de un solo campo y los índices compuestos.
Crear un índice compuesto
Para crear manualmente un índice compuesto desde la consola de GCP, sigue estos pasos:
En la Google Cloud consola, ve a la página Bases de datos.
Seleccione la base de datos que necesite de la lista de bases de datos.
En el menú de navegación, haga clic en Índices y, a continuación, en la pestaña Compuesto.
Haz clic en Crear índice.
Introduce un ID de colección. Añade los nombres de los campos que quieras indexar y un modo de indexación para cada campo. Haz clic en Guardar índice.
El nuevo índice aparecerá en la lista de índices compuestos y Firestore empezará a crearlo. Cuando se haya creado el índice, verás una marca de verificación verde junto a él.
Eliminar un índice compuesto
Para eliminar un índice compuesto, sigue estos pasos:
En la Google Cloud consola, ve a la página Bases de datos.
Seleccione la base de datos que necesite de la lista de bases de datos.
En el menú de navegación, haga clic en Índices y, a continuación, en la pestaña Compuesto.
En la lista de índices compuestos, haz clic en el botón Más
del índice que quieras eliminar. Haz clic en Eliminar.Confirma que quieres eliminar este índice haciendo clic en Eliminar índice en la alerta.
Añadir una exención de índice de campo único
Las exenciones de índices de un solo campo te permiten anular la configuración de índices automática de campos concretos de una colección. Puede añadir una exención de un solo campo desde la consola:
En la Google Cloud consola, ve a la página Bases de datos.
Seleccione la base de datos que necesite de la lista de bases de datos.
En el menú de navegación, haga clic en Índices y, a continuación, en la pestaña Campo único.
Haga clic en Añadir exención.
Introduce un ID de colección y una ruta de campo.
Selecciona la nueva configuración de indexación de este campo. Habilita o inhabilita los índices de un solo campo ascendentes, descendentes y array-contains que se actualizan automáticamente para este campo.
Haz clic en Guardar exención.
Añadir una exención a nivel de colección
Para definir una exención de índice de campo único que se aplique a todos los campos de un ID de colección, sigue estos pasos:
- Haga clic en Añadir exención.
Introduzca un ID de colección para el grupo de colecciones y defina Ruta del campo como
*
.Selecciona las exenciones de indexación que quieras aplicar a todos los campos del grupo de colecciones.
Haz clic en Guardar exención.
Eliminar una exención de índice de campo único
Para eliminar una exención de índice de un solo campo, siga estos pasos:
En la Google Cloud consola, ve a la página Bases de datos.
Seleccione la base de datos que necesite de la lista de bases de datos.
En el menú de navegación, haga clic en Índices y, a continuación, en la pestaña Campo único.
En la lista de exenciones de índice de un solo campo, haz clic en el botón Más
de la exención que quieras eliminar. Haz clic en Eliminar.Confirma que quieres eliminar esta exención haciendo clic en Eliminar en la alerta.
Cuando eliminas una exención de un solo campo, el campo o subcampo especificado utilizará la configuración de indexación heredada. Los campos de los documentos vuelven a la configuración automática de índices de tu base de datos. Los subcampos de un mapa heredan las exenciones de los campos principales antes de heredar la configuración de indexación automática.
Usar la CLI de Firebase
También puedes desplegar índices con la CLI de Firebase.
Para empezar, ejecuta firebase init firestore
en el directorio de tu proyecto.
Durante la configuración, la CLI de Firebase genera un archivo JSON con los índices predeterminados en el formato correcto. Edita el archivo para añadir más índices e impleméntalo con el comando firebase deploy
.
Para desplegar solo los índices y las reglas de Firestore, añade la marca --only firestore
.
Si editas los índices con la consola de Firebase, asegúrate de actualizar también el archivo de índices local. Consulta la referencia de definición de índice JSON.
Usar Terraform
Crear índices en la base de datos
Las bases de datos de Firestore pueden incluir índices de campo único y compuestos. Puedes editar el archivo de configuración de Terraform para crear un índice en tu base de datos.
Los índices de un solo campo y los compuestos usan tipos de recursos de Terraform distintos (google_firestore_index
y google_firestore_field
).
Índice de un solo campo
El siguiente archivo de configuración de Terraform de ejemplo crea un índice de un solo campo en el campo name
de la colección 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 {} }
- Sustituye project-id por el ID del proyecto. Los IDs de proyecto deben ser únicos.
- Sustituye database-id por el ID de tu base de datos.
Índice compuesto
El siguiente archivo de configuración de Terraform de ejemplo crea un índice compuesto para una combinación del campo name
y el campo description
de la colección 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" } }
- Sustituye project-id por el ID del proyecto. Los IDs de proyecto deben ser únicos.
- Sustituye database-id por el ID de tu base de datos.
Índice de vectores
El siguiente archivo de configuración de Terraform crea un índice vectorial en el campo embedding
de la colección 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 {} } } }
- Sustituye project-id por el ID del proyecto. Los IDs de proyecto deben ser únicos.
- Sustituye database-id por el ID de tu base de datos.
Índices del modo Datastore
También puedes crear índices del modo Datastore con 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" }
Migrar desde google_datastore_index
El recurso google_datastore_index
está obsoleto y no estará disponible en la versión 6.0.0 y posteriores de terraform-provider-google.
Si antes usabas el recurso google_datastore_index
, puedes migrar a google_firestore_index
.
Para migrar, haz lo siguiente:
- Escribe un recurso
google_firestore_index
equivalente. - Importa tu índice del modo Datastore en el nuevo recurso.
- Quita las referencias al recurso
google_datastore_index
antiguo. - Elimina el recurso
google_datastore_index
antiguo del estado de Terraform. - Ejecutando
terraform apply
para aplicar los cambios.
A continuación, se ofrecen instrucciones más detalladas:
- Escribe un
google_firestore_index
de sustitución basado en tu recursogoogle_datastore_index
. Consulta los cambios necesarios más abajo. - Determina la ruta de recurso de Firestore de tu í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 '"')
Sustituye datastore-index-resource-name por el nombre de Terraform del recurso que ya tienes.
- Importa tu índice del modo Datastore a la
google_firestore_index
que has creado anteriormente:terraform import google_firestore_index.firestore-index-resource-name $INDEX_RESOURCE_PATH
Sustituye firestore-index-resource-name por el nombre de Terraform del recurso que ya tienes.
Para obtener más información sobre cómo importar recursos de índice de Firestore, consulta la documentación de referencia de google_firestore_index.
- Elimina el recurso
google_datastore_index
de tu archivo de configuración de Terraform. - Elimina el recurso
google_datastore_index
del estado de Terraform:terraform state rm google_datastore_index.datastore-index-resource-name
Para obtener más información sobre cómo quitar recursos, consulta la página de Terraform sobre cómo quitar recursos.
- Ejecuta
terraform plan
. Verifica el resultado para confirmar que no estás creando ni destruyendo ningún recurso.Inspecciona el resultado para asegurarte de que la importación se ha completado correctamente. Si la salida muestra algún campo que cambia, asegúrate de que esos cambios son intencionados. Si el resultado incluye una línea similar a la siguiente:
google_firestore_index.firestore-index-resource-name must be replaced
A continuación, inspecciona el archivo de configuración de Terraform para ver si hay algún error.
- Cuando estés conforme con el resultado del plan de Terraform, ejecuta lo siguiente:
terraform apply
- Reemplaza
google_datastore_index
porgoogle_firestore_index
. - Sustituye el nombre del argumento
kind
porcollection
, pero mantén el mismo valor del argumento. - Sustituye el nombre del argumento
ancestor
porquery_scope
. Sustituye el valor del argumentoALL_ANCESTORS
porCOLLECTION_RECURSIVE
y cualquier otro valor porCOLLECTION_GROUP
. Si no hay ningún argumentoancestor
, añade un argumentoquery_scope
con el valorCOLLECTION_GROUP
. - Añade el argumento
api_scope
con el valorDATASTORE_MODE_API
. - Sustituye cada instancia de
properties
por la instancia correspondiente defields
. Sustituye cada instancia dename
porfield_path
y cada instancia dedirection
pororder
. Configurar un índice lleva unos minutos. El tiempo mínimo de compilación de un índice es de unos minutos, incluso en el caso de una base de datos vacía.
El tiempo de reposición depende de la cantidad de datos que haya en el nuevo índice. Cuantos más valores de campo coincidan con la definición del índice, más tiempo se tardará en rellenar el índice.
Traducir tu índice
Para traducir un recurso google_datastore_index al recurso google_firestore_index equivalente, cópialo y haz los siguientes cambios:
Por ejemplo, considera 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" } }
El recurso google_firestore_index
equivalente sería el siguiente:
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" } }
Tiempo de compilación del índice
Para crear un índice, Firestore debe configurarlo y, a continuación, rellenarlo con los datos que ya tenga. El tiempo de compilación del índice es la suma del tiempo de configuración y el tiempo de relleno:
Las compilaciones de índices son operaciones de larga duración.
Después de iniciar una compilación de índice, Firestore 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 firestore 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 firestore operations list
Comprobar el estado de la operación
En lugar de enumerar todas las operaciones de larga duración, puedes consultar los detalles de una sola operación:
gcloud firestore operations describe operation-name
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 documentos. workEstimated
muestra el número total estimado de documentos que procesará una operación. workCompleted
muestra el número de documentos procesados hasta el momento. Una vez completada la operación, workCompleted
refleja el número total de documentos 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 del progreso de una compilación 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" } }, }, ...
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.
Errores de creación de índices
Es posible que se produzcan errores de compilación de índices al gestionar índices compuestos y exenciones de índices de un solo campo. Una operación de indexación puede fallar si Firestore detecta un problema con los datos que está indexando. Lo más habitual es que hayas alcanzado un límite de índice. Por ejemplo, es posible que la operación haya alcanzado el número máximo de entradas de índice por documento.
Si no se puede crear el índice, verás el mensaje de error en la consola. Después de verificar que no has alcanzado ningún límite de índice, vuelve a intentar la operación de índice.