Índices

Cada consulta de Firestore en modo Datastore calcula los resultados mediante uno o más índices que contienen claves de entidad en una secuencia especificada por las propiedades del índice y, de manera opcional, por los principales de la entidad. Los índices se actualizan a fin de mostrar cualquier cambio que haga la aplicación a sus entidades, de modo que estén disponibles los resultados correctos de todas las consultas sin realizar procesamiento adicional.

Existen dos tipos de índices:

Índices integrados
De forma predeterminada, una base de datos en modo Datastore predefine de forma automática un índice para las propiedades de cada categoría de entidad. Estos índices de propiedad única son adecuados para las consultas simples.
Índices compuestos
Los índices compuestos indexan múltiples valores de propiedad por cada entidad indexada. Los índices compuestos admiten consultas complejas y se definen en un archivo de configuración de índice (index.yaml).

Analizaremos los tipos de índices con más detalle más adelante.

Definición y estructura de los índices

Un índice se define en una lista de propiedades de una categoría de entidad determinada, con un orden correspondiente (ascendente o descendente) para cada propiedad. El índice también puede incluir las entidades principales de la entidad para usarlas en las consultas principales.

Un índice contiene entradas para cada propiedad mencionada en la definición del índice. Cada entrada del índice representa una entidad que es un resultado potencial de las consultas basadas en el índice. Una entidad solo se incluye en el índice si tiene un valor indexado configurado para cada propiedad que se usa en el índice; si la definición del índice hace referencia a una propiedad para la cual la entidad no tiene valor, esa entidad no aparecerá en el índice y nunca se mostrará como resultado de ninguna consulta basada en el índice.

El índice compuesto se ordena primero por entidad principal y, luego, por los valores de las propiedades, en el orden especificado en la definición del índice. Con base en esta comprensión, puedes crear el índice perfecto que permite realizar consultas eficientes.

Configuración de índices

Firestore en modo Datastore proporciona índices integrados o automáticos para las consultas de los siguientes tipos:

  • Consultas sin categoría solo con filtros de entidad principal y de clave
  • Consultas solo con filtros de entidad principal y de igualdad
  • Consultas solo con filtros de desigualdad (limitados a una única propiedad)
  • Consultas solo con filtros de entidad principal, filtros de igualdad en propiedades y filtros de desigualdad en claves
  • Consultas sin filtros y solo con un orden de clasificación en una propiedad, ya sea ascendente o descendente

Como ejemplo, de forma predeterminada, las bases de datos en modo Datastore predefinen de forma automática dos índices de propiedades únicas para cada propiedad de cada categoría de entidad, uno en orden ascendente y otro en orden descendente. Si no quieres que tu base de datos mantenga un índice para una propiedad, excluye la propiedad de tus índices. Ten en cuenta que si excluyes una propiedad, la quitarás de cualquier índice compuesto.

Los índices integrados permiten realizar muchas consultas sencillas, como consultas de solo igualdad y consultas de desigualdad simples.

Los índices integrados no aparecen en la página Índices de la consola de Google Cloud.

Para realizar consultas más complejas, una aplicación debe definir índices compuestos o manuales. Los índices compuestos son obligatorios para los siguientes tipos de consultas:

  • Consultas con filtros principales y de desigualdad
  • Consultas con uno o más filtros de desigualdad en una propiedad y uno o más filtros de igualdad en otras propiedades
  • Consultas con un orden de clasificación en las claves, en orden descendente
  • Consultas con varios órdenes de clasificación
  • Consultas con uno o más filtros y uno o más órdenes de clasificación

Los índices compuestos se definen en el archivo de configuración de índice de la aplicación (index.yaml). Los índices integrados no están contenidos en este archivo.

Los índices compuestos constan de varias propiedades y requieren que cada propiedad individual no esté excluida de los índices.

Los índices compuestos se pueden ver en la página Índices de la consola de Google Cloud. No puedes usar la consola de Google Cloud para crear o actualizar índices compuestos.

Si la aplicación intenta realizar una consulta que no puede ejecutarse con los índices disponibles (ya sean integrados o especificados en el archivo de configuración de índices), la consulta fallará.

La API del modo de Datastore sugiere de forma automática índices que son apropiados para la mayoría de las aplicaciones. Según el tamaño y la forma de tus datos y el uso que haga tu aplicación de la base de datos en modo Datastore, pueden justificarse los ajustes manuales a tus índices. Por ejemplo, las operaciones de escritura de entidades con múltiples valores de propiedad pueden dar como resultado un índice con alto crecimiento que tiene un costo de almacenamiento elevado y una mayor latencia de escritura.

El emulador de Datastore puede ayudar a facilitar la administración del archivo de configuración de índice. En lugar de no ejecutar una consulta que requiere un índice y no tiene uno, el emulador de Datastore puede generar una configuración de índice que permita que la consulta se realice de forma correcta. Si tus pruebas locales de una aplicación abarcan todas las consultas posibles que puede realizar la aplicación, con todas las combinaciones de filtro y órdenes de clasificación, las entradas generadas representarán un conjunto completo de índices. Si tus pruebas no abarcan todas las formas de consultas posibles, puedes revisar y ajustar el archivo de configuración de índices antes de actualizarlos.

Puedes obtener más información sobre index.yaml en la configuración de índices.

Implementa o borra índices

Cuando termines de modificar tu archivo de configuración de índices, ejecuta el comando gcloud datastore indexes create para que funcionen los índices. Para obtener más información, consulta cómo actualizar los índices.

Si antes implementaste índices que ya no necesitas, puedes borrar los índices sin usar.

Costos de almacenamiento y latencia de escritura

Los índices contribuyen a los costos de almacenamiento. En Tamaño de entrada de índice, se describe cómo los índices integrados y compuestos contribuyen al tamaño de almacenamiento de la base de datos. Puedes usar las estadísticas de Firestore en modo Datastore para ver más información sobre las entradas de índice y el tamaño del almacenamiento.

Los índices también contribuyen a la latencia de escritura. Cuando se actualiza un valor de propiedad, la base de datos también actualiza todos los índices relacionados. Cuantos más índices necesite actualizar la base de datos, más tiempo tardará la operación.

Para reducir los costos de almacenamiento y mejorar el rendimiento de escritura, borra los índices sin usar y excluye las propiedades de la indexación. Esto también evita que las operaciones fallen debido a los límites de índice.

Índices y propiedades

A continuación, se presentan algunas consideraciones especiales para tener en cuenta sobre los índices y cómo se relacionan con las propiedades de tus entidades:

Propiedades con tipos de valores mixtos

Cuando dos entidades tienen propiedades con el mismo nombre, pero diferentes tipos de valor, un índice de la propiedad clasifica las entidades primero por tipo de valor y luego por un orden secundario apropiado para cada tipo. Por ejemplo, si dos entidades tienen una propiedad llamada age, una con un valor de número entero y otra con un valor de string, la entidad con el valor de número entero siempre precede a la que tiene el valor de string cuando se ordena por la propiedad age, sin importar los valores de la propiedad en sí.

Esto es importante en particular en el caso de los números enteros y los números de punto flotante, que se tratan como tipos diferentes según el modo Datastore. Debido a que todos los números enteros se ordenan antes que los números flotantes, una propiedad con el valor de número entero 38 aparece antes que una con el valor de punto flotante 37.5.

Propiedades excluidas

Si sabes que nunca deberás filtrar ni ordenar según una propiedad en particular, puedes indicar a tu base de datos en modo Datastore que no mantenga entradas de índice para esa propiedad si la excluyes de los índices. Esto reduce el costo de ejecutar tu aplicación, ya que disminuye el espacio de almacenamiento necesario para las entradas de índice. Esto también puede mejorar la latencia de escritura. Una entidad con una propiedad excluida se comporta como si la propiedad no estuviera configurada: las consultas con un filtro o un orden de clasificación en la propiedad excluida nunca mostrarán esa entidad.

La propiedad description del ejemplo siguiente se excluye de los índices:

C#

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de C# de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

Entity task = new Entity()
{
    Key = _db.CreateKeyFactory("Task").CreateKey("sampleTask"),
    ["category"] = "Personal",
    ["created"] = new DateTime(1999, 01, 01, 0, 0, 0, DateTimeKind.Utc),
    ["done"] = false,
    ["priority"] = 4,
    ["percent_complete"] = 10.0,
    ["description"] = new Value()
    {
        StringValue = "Learn Cloud Datastore",
        ExcludeFromIndexes = true
    },
};

Go

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Go de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

type Task struct {
	Category        string
	Done            bool
	Priority        int
	Description     string `datastore:",noindex"`
	PercentComplete float64
	Created         time.Time
}
task := &Task{
	Category:        "Personal",
	Done:            false,
	Priority:        4,
	Description:     "Learn Cloud Datastore",
	PercentComplete: 10.0,
	Created:         time.Now(),
}

Java

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Java de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

Entity task =
    Entity.newBuilder(taskKey)
        .set("category", "Personal")
        .set("created", Timestamp.now())
        .set("done", false)
        .set("priority", 4)
        .set("percent_complete", 10.0)
        .set(
            "description",
            StringValue.newBuilder("Learn Cloud Datastore").setExcludeFromIndexes(true).build())
        .build();

Node.js

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Node.js de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

const task = [
  {
    name: 'category',
    value: 'Personal',
  },
  {
    name: 'created',
    value: new Date(),
  },
  {
    name: 'done',
    value: false,
  },
  {
    name: 'priority',
    value: 4,
  },
  {
    name: 'percent_complete',
    value: 10.0,
  },
  {
    name: 'description',
    value: 'Learn Cloud Datastore',
    excludeFromIndexes: true,
  },
];

PHP

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de PHP de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

$task = $datastore->entity(
    $key,
    [
        'category' => 'Personal',
        'created' => new DateTime(),
        'done' => false,
        'priority' => 4,
        'percent_complete' => 10.0,
        'description' => 'Learn Cloud Datastore'
    ],
    ['excludeFromIndexes' => ['description']]
);

Python

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Python de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

key = client.key("Task")
task = datastore.Entity(key, exclude_from_indexes=("description",))
task.update(
    {
        "category": "Personal",
        "description": "Learn Cloud Datastore",
        "created": datetime.datetime.now(tz=datetime.timezone.utc),
        "done": False,
        "priority": 4,
        "percent_complete": 10.5,
    }
)
client.put(task)

Ruby

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Ruby de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

task = datastore.entity "Task" do |t|
  t["category"] = "Personal"
  t["created"] = Time.now
  t["done"] = false
  t["priority"] = 4
  t["percent_complete"] = 10.0
  t["description"] = "Learn Cloud Datastore"
  t.exclude_from_indexes! "description", true
end

GQL

No aplicable

La consulta del siguiente ejemplo no mostrará ningún resultado si se excluyó la propiedad description:

C#

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de C# de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

Query query = new Query("Task")
{
    Filter = Filter.Equal("description", "Learn Cloud Datastore")
};

Go

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Go de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

query := datastore.NewQuery("Tasks").
	FilterField("Description", "=", "A task description")

Java

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Java de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

Query<Entity> query =
    Query.newEntityQueryBuilder()
        .setKind("Task")
        .setFilter(PropertyFilter.eq("description", "A task description"))
        .build();

Node.js

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Node.js de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

const query = datastore
  .createQuery('Task')
  .filter(new PropertyFilter('description', '=', 'A task description.'));

PHP

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de PHP de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

$query = $datastore->query()
    ->kind('Task')
    ->filter('description', '=', 'A task description.');

Python

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Python de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

query = client.query(kind="Task")
query.add_filter(filter=PropertyFilter("description", "=", "Learn Cloud Datastore"))

Ruby

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Ruby de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

query = datastore.query("Task")
                 .where("description", "=", "A task description.")

GQL


# Will not return any results!
SELECT * FROM Task WHERE description = 'A task description.'

Más adelante, puedes volver a indexar la propiedad.

Sin embargo, ten en cuenta que cambiar una propiedad de excluida a indexada no afecta a ninguna entidad existente que se haya creado antes del cambio. Las consultas que filtren según la propiedad no mostrarán esas entidades existentes, ya que las entidades no se escribieron en el índice de la consulta cuando se crearon. Para que las consultas futuras puedan acceder a las entidades, debes volver a escribirlas en tu base de datos para que se ingresen en los índices correspondientes. Es decir, debes hacer lo siguiente para cada una de esas entidades:

  1. Buscar (get) la entidad.
  2. Escribir (put) la entidad de nuevo en tu base de datos.

Del mismo modo, cambiar una propiedad de indexada a excluida solo afecta a las entidades que se escribirán en tu base de datos más adelante. Las entradas de índice de cualquier entidad actual con esa propiedad existirán hasta que se actualicen o borren las entidades. Para evitar resultados no deseados, debes quitar todas las consultas de tu código que filtran o clasifican según la propiedad (ahora excluida).

Límites de índice

Firestore en modo Datastore impone límites en la cantidad y el tamaño general de las entradas de índice que se pueden asociar con una sola entidad. Estos límites son grandes y la mayoría de las aplicaciones no se ven afectadas. Sin embargo, hay circunstancias en las que puedes encontrarte con estos límites.

Como se describió antes, una base de datos en modo Datastore crea una entrada en un índice predefinido para las propiedades de cada entidad, excepto aquellas que declaraste de forma explícita como excluidas de tus índices. La propiedad también se puede incluir en índices personalizados adicionales declarados en tu archivo de configuración de índices (index.yaml). Siempre que una entidad no tenga propiedades de lista, tendrá como máximo una entrada en cada índice personalizado (para índices que no sean principales) o una para cada una de las principales de la entidad (para índices principales). Cada una de estas entradas de índice debe actualizarse cada vez que cambie el valor de la propiedad.

En el caso de una propiedad que tiene un valor único para cada entidad, cada valor posible debe almacenarse solo una vez por entidad en el índice predefinido de la propiedad. Pese a ello, es posible que una entidad con un gran número de estas propiedades de valor único supere el límite de entradas o de tamaño del índice. De manera similar, una entidad que puede tener múltiples valores para la misma propiedad requiere una entrada de índice distinta para cada valor. De la misma forma, si el número de valores posibles es grande, esta entidad puede superar el límite de entradas.

La situación empeora en el caso de las entidades con varias propiedades, cada una de las cuales puede asumir varios valores. A fin de alojar una entidad de este tipo, el índice debe incluir una entrada para cada combinación posible de valores de propiedad. Los índices personalizados que hacen referencia a varias propiedades, cada una con múltiples valores, son susceptibles a un “crecimiento” combinatorio y pueden requerir un gran número de entradas para una entidad con una cantidad relativamente pequeña de valores de propiedad posibles. Estos índices con alto crecimiento pueden aumentar en gran medida el tamaño de almacenamiento de una entidad debido a la gran cantidad de entradas de índice que deben almacenarse. Los índices con alto crecimiento también pueden hacer que la entidad exceda el recuento de entradas del índice o el límite de tamaño.

Considera el siguiente código:

C#

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de C# de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

Entity task = new Entity()
{
    Key = _db.CreateKeyFactory("Task").CreateKey("sampleTask"),
    ["tags"] = new ArrayValue() { Values = { "fun", "programming", "learn" } },
    ["collaborators"] = new ArrayValue() { Values = { "alice", "bob", "charlie" } },
    ["created"] = DateTime.UtcNow
};

Go

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Go de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

task := &Task{
	Tags:          []string{"fun", "programming", "learn"},
	Collaborators: []string{"alice", "bob", "charlie"},
	Created:       time.Now(),
}

Java

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Java de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

Entity task =
    Entity.newBuilder(taskKey)
        .set("tags", "fun", "programming", "learn")
        .set("collaborators", "alice", "bob", "charlie")
        .set("created", Timestamp.now())
        .build();

Node.js

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Node.js de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

const task = {
  method: 'insert',
  key: datastore.key('Task'),
  data: {
    tags: ['fun', 'programming', 'learn'],
    collaborators: ['alice', 'bob', 'charlie'],
    created: new Date(),
  },
};

PHP

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de PHP de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

$task = $datastore->entity(
    $datastore->key('Task'),
    [
        'tags' => ['fun', 'programming', 'learn'],
        'collaborators' => ['alice', 'bob', 'charlie'],
        'created' => new DateTime(),
    ]
);

Python

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Python de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

task = datastore.Entity(client.key("Task"))
task.update(
    {
        "tags": ["fun", "programming", "learn"],
        "collaborators": ["alice", "bob", "charlie"],
        "created": datetime.datetime.now(tz=datetime.timezone.utc),
    }
)

Ruby

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud Datastore, consulta Bibliotecas cliente de Cloud Datastore. Si deseas obtener más información, consulta la documentación de referencia de la API de Ruby de Cloud Datastore.

Para autenticarte en Cloud Datastore, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

task = datastore.entity "Task" do |t|
  t["tags"] = ["fun", "programming", "learn"]
  t["collaborators"] = ["alice", "bob", "charlie"]
  t["created"] = Time.now
end

GQL

No aplicable

Crea una entidad Task con tres valores para la propiedad tags, tres para la propiedad collaborators y created establecido en la fecha actual. Esto requerirá 9 entradas de índice, una para cada combinación posible de valores de propiedad:

('fun', 'alice', NOW())
('fun', 'bob', NOW())
('fun', 'charlie', NOW())

('programming', 'alice', NOW())
('programming', 'bob', NOW())
('programming', 'charlie', NOW())

('learn', 'alice', NOW())
('learn', 'bob', NOW())
('learn', 'charlie', NOW())

Cuando la misma propiedad se repite varias veces, Firestore en modo Datastore puede detectar índices con alto crecimiento y sugerir un índice alternativo. Sin embargo, en todas las demás circunstancias (como la consulta definida en este ejemplo), una base de datos en modo Datastore generará un índice con alto crecimiento. En este caso, puedes evitar el índice con alto crecimiento si configuras de forma manual un índice en tu archivo de configuración de índices:

indexes:
- kind: Task
  properties:
  - name: tags
  - name: created
- kind: Task
  properties:
  - name: collaborators
  - name: created

Esto reduce la cantidad de entradas necesarias a solo (|tags| * |created| + |collaborators| * |created|), o 6 entradas en lugar de 9:

('fun', NOW())
('programming', NOW())
('learn', NOW())

('alice', NOW())
('bob', NOW())
('charlie', NOW())

Cualquier operación commit que haga que un índice supere los límites de entradas de índice o de tamaño fallará. En el texto del error, se describe qué límite se superó ("Too many indexed properties" o "Index entries too large") y qué índice personalizado fue la causa. Si creas un índice nuevo que excede los límites para cualquier entidad cuando se compila, las consultas en el índice fallarán y el índice aparecerá con el estado Error en la consola de Google Cloud. Para manejar estos índices Error, haz lo siguiente:

  1. Quita el índice de tu archivo de configuración de índices (index.yaml).
  2. Con Google Cloud CLI, quita el índice de la base de datos con el comando datastore indexes cleanup, como se describe en Borra índices sin usar.
  3. Sigue uno de estos pasos:
    • Reformula la definición del índice y las consultas correspondientes.
    • Quita las entidades que generan la explosión del índice.
  4. Vuelve a agregar el índice a index.yaml.
  5. Con Google Cloud CLI, ejecuta el comando datastore indexes create para agregar el índice a la base de datos, como se describe en Actualiza índices.

Puedes evitar los índices con alto crecimiento si evitas las consultas que requieren un índice personalizado con una propiedad de lista. Como se describió antes, esto incluye consultas con varios órdenes de clasificación o con una combinación de filtros de igualdad y desigualdad.

Índices para proyecciones

Las consultas de proyección requieren que todas las propiedades especificadas en la proyección se incluyan en un índice. El emulador de Datastore genera automáticamente los índices necesarios en el archivo de configuración de índices, index.yaml, que se sube con la aplicación.

Una manera de minimizar el número de índices requeridos es proyectar las mismas propiedades coherentemente, incluso si no las necesitas todas siempre. Por ejemplo, estas consultas requieren dos índices diferentes:

SELECT priority, percent_complete FROM Task

SELECT priority, percent_complete, created FROM Task

Sin embargo, si siempre proyectas las propiedades priority, percent_complete y created, aunque created no sea obligatoria, solo se necesitará un índice.

Convertir una consulta existente en una consulta de proyección puede requerir que se cree un índice nuevo si las propiedades de la proyección no están incluidas en otra parte de la consulta. Por ejemplo, supongamos que tienes una consulta existente como esta:

SELECT * FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

La consulta requiere el siguiente índice:

indexes:
- kind: Task
  properties:
  - name: priority
  - name: percent_complete

Convertir esto en cualquiera de estas consultas de proyección

SELECT created FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

SELECT priority, percent_complete, created FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

ingresa una nueva propiedad (created) y, por lo tanto, requerirá la compilación de un índice nuevo:

indexes:
- kind: Task
  properties:
  - name: priority
  - name: percent_complete
  - name: created

Sin embargo,

SELECT priority, percent_complete FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

no cambiaría el índice requerido, debido a que las propiedades proyectadas priority y percent_complete ya estaban incluidas en la consulta existente.

Múltiples bases de datos

Puedes usar gcloud firestore a fin de administrar un solo índice para el modo Datastore o usar gcloud datastore con un archivo index.yaml a fin de administrar todos los índices de una base de datos.

gcloud firestore
gcloud firestore indexes composite create --api-scope=datastore-mode-api  --query-scope=QUERY_SCOPE --database=DATABASE_ID
gcloud datastore
gcloud alpha datastore indexes create index.yaml --database=DATABASE_ID

Reemplaza lo siguiente:

  • DATABASE_ID: Un ID de base de datos.
  • QUERY_SCOPE: Puede ser collection-recursive para los índices principales o collection-group para los índices no principales.