Administra índices

Firestore garantiza el rendimiento de las consultas, ya que usa índices en todas ellas. Los índices necesarios para las consultas más básicas se crean de forma automática. A medida que usas y pruebas tu app, Cloud Firestore genera mensajes de error que te ayudan a crear los índices adicionales necesarios. En esta página, se describe cómo administrar los índices de campo único, compuestos y [vector][vector].

Crea un índice faltante a través de un mensaje de error

Si intentas realizar una consulta compuesta con una cláusula de rango que no corresponda a un índice existente, recibirás un error. En el mensaje de error, se incluye un vínculo directo para crear el índice que falta en Firebase console.

Usa el vínculo generado para ir a Firebase console, revisa la información que se propagó deforma automática y haz clic en Crear.

En caso de que se requiera un índice vectorial, el mensaje de error incluirá un comando de Google Cloud CLI para crear el índice vectorial faltante. Ejecuta el comando para crear el índice faltante.

Funciones y permisos

Antes de crear un índice en Firestore, asegúrate de tener asignado alguno de los siguientes roles:

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

Si definiste 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

Usa Google Cloud Platform Console

Desde Google Cloud Platform Console, puedes administrar las exenciones para la indexación de los campos únicos y los índices compuestos.

Crea un índice compuesto

Para crear manualmente un índice compuesto nuevo desde GCP Console, sigue estos pasos:

  1. En la consola de Google Cloud, ve a la página Bases de datos.

    Ir a Bases de datos

  2. Selecciona la base de datos requerida de la lista.

  3. En el menú de navegación, haz clic en Índices y, luego, en la pestaña Compuestos.

  4. Haz clic en Crear índice.

  5. Ingresa un ID de colección. Agrega los nombres de los campos que deseas indexar y un modo de índice para cada campo. Haz clic en Guardar índice.

Tu índice nuevo aparecerá en la lista de índices compuestos y Firestore comenzará a crear el índice. Cuando termine de crearse, verás una marca de verificación verde junto al índice.

Cómo borrar un índice compuesto

Sigue estos pasos para borrar un índice compuesto:

  1. En la consola de Google Cloud, ve a la página Bases de datos.

    Ir a Bases de datos

  2. Selecciona la base de datos requerida de la lista.

  3. En el menú de navegación, haz clic en Índices y, luego, en la pestaña Compuestos.

  4. En la lista de índices compuestos, haz clic en el botón Más del índice que deseas borrar. Haz clic en Borrar.

  5. Para confirmar que deseas borrar este índice, haz clic en Borrar índice en la alerta.

Agrega una exención de índice de campo único

Las exenciones de índices de campo único te permiten anular la configuración automática de los índices en campos específicos de una colección. Para agregar una exención de campo único desde la consola, sigue estos pasos:

  1. En la consola de Google Cloud, ve a la página Bases de datos.

    Ir a Bases de datos

  2. Selecciona la base de datos requerida de la lista.

  3. En el menú de navegación, haz clic en Índices y, luego, en la pestaña De campo único.

  4. Haz clic en Agregar exención.

  5. Ingresa un ID de colección y una ruta de campo.

  6. Selecciona una configuración de indexación nueva para este campo. Habilita o inhabilita automáticamente los índices ascendentes, descendentes y de campo único de arreglos actualizados para este campo.

  7. Haz clic en Guardar exención.

Agrega una exención a nivel de la colección

Para definir una exención de índice de campo único que se aplique a todos los campos de un ID de recopilación, haz lo siguiente:

  1. Haz clic en Agregar exención.
  2. Ingresa un ID de colección para el grupo de colecciones y establece Ruta de campo como *.

    Elige el campo que quieres excluir

  3. Selecciona las exenciones de indexación que deseas aplicar a todos los campos del grupo de colecciones.

  4. Haz clic en Guardar exención.

Borra una exención de índice de campo único

Para borrar una exención de índice de campo único, sigue estos pasos:

  1. En la consola de Google Cloud, ve a la página Bases de datos.

    Ir a Bases de datos

  2. Selecciona la base de datos requerida de la lista.

  3. En el menú de navegación, haz clic en Índices y, luego, en la pestaña De campo único.

  4. En la lista de exenciones de índice de campo único, haz clic en el botón Más para la exención que deseas borrar. Haz clic en Borrar.

  5. Para confirmar que deseas borrar esta exención, haz clic en Eliminar en la alerta.

Cuando borras una exención de campo único, el subcampo o campo especificado usará la configuración de indexación heredada. Los campos de documentos vuelven a la configuración automática de índice de la base de datos. Los subcampos de un mapa heredan las exenciones de los campos superiores antes de heredar la configuración automática de índice.

Usa Firebase CLI

También puedes implementar índices con Firebase CLI. Para comenzar, ejecuta firebase init firestore en el directorio de tu proyecto. Durante la configuración, Firebase CLI genera un archivo JSON con los índices predeterminados en el formato correcto. Edita el archivo para agregar más índices y, luego, impleméntalo con el comando firebase deploy.

Para implementar solo índices y reglas de Firestore, agrega la marca --only firestore.

Si haces modificaciones en los índices con Firebase console, asegúrate de actualizar también tu archivo de índices local. Consulta la referencia de definición de índice JSON.

Usar Terraform

Crea í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 para tu base de datos. Los índices de campo único y los compuestos usan tipos de recursos de Terraform distintos (google_firestore_index y google_firestore_field).

Se admiten los índices del modo nativo y del modo Datastore de Firestore.

Índice de campo único

En el siguiente ejemplo de archivo de configuración de Terraform, se crea un índice de campo único 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 {}
}
  • Reemplaza project-id con el ID del proyecto. Los ID de proyecto deben ser únicos.
  • Reemplaza database-id por el ID de tu base de datos.

Índice compuesto

En el siguiente ejemplo de archivo de configuración de Terraform, se crea un índice compuesto para una combinación del campo name y 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"
  }

}
  • Reemplaza project-id con el ID del proyecto. Los ID de proyecto deben ser únicos.
  • Reemplaza database-id por el ID de tu base de datos.

Índice vectorial

En el siguiente ejemplo de archivo de configuración de Terraform, se 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 {}
    }
  }
}
  • Reemplaza project-id con el ID del proyecto. Los ID de proyecto deben ser únicos.
  • Reemplaza database-id por el ID de tu base de datos.

Índices del modo Datastore

También puedes crear índices de modo de almacén de datos 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"
}
Cómo migrar desde google_datastore_index

El recurso google_datastore_index dejó de estar disponible y no estará disponible en la versión 6.0.0 de terraform-provider-google y versiones posteriores.

Si antes usabas el recurso google_datastore_index, puedes migrar a google_firestore_index. Para migrar, haz lo siguiente:

  1. Escribe un recurso google_firestore_index equivalente.
  2. Importa tu índice existente del modo Datastore al recurso nuevo.
  3. Quita las referencias al recurso google_datastore_index anterior.
  4. Quita el recurso google_datastore_index anterior del estado de Terraform.
  5. Ejecutar terraform apply para aplicar los cambios

A continuación, se incluyen instrucciones más detalladas:

  1. Escribe un google_firestore_index de reemplazo según tu recurso google_datastore_index existente. Consulta más abajo para conocer los cambios necesarios.
  2. Determina la ruta de acceso al 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 '"')
    

    Reemplaza datastore-index-resource-name por el nombre de Terraform de tu recurso existente.

  3. Importa tu índice existente del modo Datastore al recurso google_firestore_index que creaste antes:

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

    Reemplaza firestore-index-resource-name por el nombre de Terraform de tu recurso existente.

    Para obtener más información sobre cómo importar recursos de índices de Firestore, consulta la documentación de referencia de google_firestore_index.

  4. Borra el recurso google_datastore_index existente de tu archivo de configuración de Terraform.
  5. Quita el recurso google_datastore_index existente 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.

  6. 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 haya completado correctamente. Si el resultado muestra que hay campos que cambian, asegúrate de que estos cambios sean los deseados. Si el resultado incluye una línea similar a la siguiente:

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

    Luego, inspecciona el archivo de configuración de Terraform para ver si hay algún error.

  7. Una vez que estés conforme con el resultado del plan de Terraform, ejecuta lo siguiente:

    terraform apply
    

  8. Cómo traducir tu índice

    Para traducir un recurso google_datastore_index al recurso google_firestore_index equivalente, cópialo y realiza los siguientes cambios:

    • Reemplaza google_datastore_index por google_firestore_index.
    • Reemplaza el nombre del argumento kind por collection, pero mantén el valor del argumento igual.
    • Reemplaza el nombre del argumento ancestor por query_scope. Reemplaza el valor del argumento ALL_ANCESTORS por COLLECTION_RECURSIVE y cualquier otro valor por COLLECTION_GROUP. Si no había un argumento ancestor, agrega un argumento query_scope con el valor COLLECTION_GROUP.
    • Agrega el argumento api_scope con el valor DATASTORE_MODE_API.
    • Para cada instancia de properties, reemplázala por una instancia correspondiente de fields. Reemplaza cada instancia de name por field_path y cada instancia de direction por order.

    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 de índices

    Para compilar un índice, Firestore debe configurar el índice y, luego, reabastecerlo con los datos existentes. El tiempo de compilación del índice es la suma del tiempo de configuración y el tiempo de reabastecimiento:

    • La configuración de un índice tarda unos minutos. El tiempo de compilación mínimo de un índice es de unos minutos, incluso para una base de datos vacía.

    • El tiempo de reabastecimiento depende de la cantidad de datos existentes en el índice nuevo. Cuantos más valores de campo coincidan con la definición del índice, más tiempo tardará en reabastecerse el índice.

    Las compilaciones de índices son operaciones de larga duración.

    Después de iniciar una compilación de índice, Firestore le asigna un nombre único a la operación. Los nombres de las operaciones incluyen el prefijo projects/[PROJECT_ID]/databases/(default)/operations/. Por ejemplo:

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

    Sin embargo, puedes omitir el prefijo cuando especifiques el nombre de una operación para el comando describe.

    Enumera todas las operaciones de larga duración

    Para enumerar las operaciones de larga duración, usa el comando gcloud firestore operations list. Este comando enumera las operaciones en curso y las que se completaron recientemente. Las operaciones se enumeran durante algunos días luego de completarse:

    gcloud firestore operations list
    

    Verifica el estado de la operación

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

    gcloud firestore operations describe operation-name

    Estima la hora de finalización

    A medida que se ejecuta tu operación, mira el valor del campo state para conocer el estado general.

    Una solicitud del estado de una operación de larga duración también muestra las métricas workEstimated y workCompleted. Estas métricas se muestran para la cantidad de documentos. workEstimated muestra la cantidad total estimada de documentos que procesará una operación. workCompleted muestra la cantidad de documentos procesados hasta el momento. Una vez que se completa la operación, workCompleted refleja la cantidad total de documentos que se procesaron, que podría ser diferente del valor de workEstimated.

    Divide workCompleted entre workEstimated para obtener una estimación aproximada del progreso. Es posible que la estimación sea inexacta, ya que depende de la demora en la recopilación de estadísticas.

    Por ejemplo, este es el estado de 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 realiza una operación, su descripción contendrá "done": true. Consulta el valor del campo state para ver el resultado de la operación. Si el campo done no está establecido en la respuesta, su valor es false. No dependas de la existencia del valor done para las operaciones en curso.

    Errores en la compilación de índices

    Es posible que encuentres errores en la compilación de los índices cuando administres índices compuestos y exenciones de índices de campo único. Una operación de indexación puede fallar si Firestore encuentra un problema en los datos que se están indexando. Por lo general, esto quiere decir que alcanzaste el límite de índices. Por ejemplo, es posible que la operación haya alcanzado la cantidad máxima de entradas permitidas en un índice de un documento.

    Si falla la creación de los índices, aparecerá un mensaje de error en la consola. Luego de verificar que no alcanzaste ningún límite de índices, reintenta la operación de índices.