Consultar con filtros de intervalo y de desigualdad en varias propiedades

Firestore en el modo de Datastore admite el uso de filtros de intervalo y de desigualdad en varias propiedades en una sola consulta. Esta función te permite usar condiciones de intervalo y de desigualdad en varias propiedades, así como simplificar el desarrollo de tu aplicación delegando la implementación de la lógica de postfiltrado en Firestore en modo Datastore.

Filtros de intervalo y de desigualdad en varias propiedades

La siguiente consulta usa filtros de intervalo en la prioridad y los días para devolver todas las tareas con una prioridad superior a cuatro y con menos de tres días para completarse.

Go

query := datastore.NewQuery("Task").
   FilterField("priority", ">", 4).
   FilterField("days", "<", 3).

GQL

SELECT * FROM /tasks WHERE priority > 4 AND days < 3;

Java

Query<Entity> query =
    Query.newEntityQueryBuilder()
      .setKind("Task")
      .setFilter(
        CompositeFilter.and(
            PropertyFilter.gt("priority", 4), PropertyFilter.lt("days", 3)))
    .build();

Node.js

const query = datastore
  .createQuery('Task')
  .filter(
    and([
      new PropertyFilter('priority', '>', 4),
      new PropertyFilter('days', '<', 3),
    ])
  );

Python

from google.cloud import datastore
client = datastore.Client()
query = client.query(kind="Task")
query.add_filter(filter=PropertyFilter("priority", ">", 4))
query.add_filter(filter=PropertyFilter("days", "<", 3))

PHP

$query = $datastore->query()
    ->kind('Task')
    ->filter('priority', '>', 4)
    ->filter('days', '<', 3)

C#

Query query = new Query("Task")
{
  Filter = Filter.And(Filter.GreaterThan("priority", 4),
    Filter.LessThan("days", 3))
};

Ruby

query = datastore.query("Task")
                 .where("priority", ">", 4)
                 .where("days", "<", 3)

Consideraciones sobre la indexación

Antes de empezar a ejecutar consultas, asegúrate de haber leído información sobre las consultas.

Si no se especifica ninguna cláusula ORDER BY, Firestore en modo Datastore usa cualquier índice que pueda satisfacer la condición de filtro de la consulta para servirla. Este enfoque genera un conjunto de resultados ordenado según la definición del índice.

Para optimizar el rendimiento y el coste de las consultas de Firestore en el modo de Datastore, optimiza el orden de las propiedades en el índice. Para ello, asegúrate de que tu índice esté ordenado de izquierda a derecha para que la consulta se limite a un conjunto de datos que impida el análisis de entradas de índice extrañas.

Por ejemplo, supongamos que quieres buscar en una colección de empleados a los que residen en Estados Unidos,cuyo salario es superior a 100.000 $y que tienen más de 0 años de experiencia. Según tu conocimiento del conjunto de datos, sabes que la restricción de salario es más selectiva que la de experiencia. Un índice que reduce el número de análisis de índices es el (salary [...], experience [...])índice. Por lo tanto, las consultas rápidas y rentables ordenan salary antes de experience, como se muestra en el siguiente ejemplo:

GQL

SELECT *
FROM /employees
WHERE salary > 100000 AND experience > 0
ORDER BY salary, experience

Java

Query<Entity> query =
  Query.newEntityQueryBuilder()
    .setKind("employees")
    .setFilter(
        CompositeFilter.and(
            PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
    .setOrderBy(OrderBy("salary"), OrderBy("experience"))
    .build();

Node.js

const query = datastore
  .createQuery("employees")
  .filter(
    and([
      new PropertyFilter("salary", ">", 100000),
      new PropertyFilter("experience", ">", 0),
       ])
    )
  .order("salary")
  .order("experience");

Python

query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.add_filter("experience", ">", 0)
query.order = ["-salary", "-experience"]

Prácticas recomendadas para optimizar los índices

Cuando optimices los índices, ten en cuenta las siguientes prácticas recomendadas.

Ordenar las consultas por igualdades seguidas del campo de intervalo o desigualdad más selectivo

Firestore en modo Datastore usa las propiedades situadas más a la izquierda de un índice compuesto para cumplir las restricciones de igualdad y las restricciones de intervalo y desigualdad, si las hay, del primer campo de la consulta orderBy(). Estas restricciones pueden reducir el número de entradas de índice que escanea Firestore en el modo de Datastore. Firestore en el modo de Datastore usa las propiedades restantes del índice para satisfacer otras restricciones de intervalo y desigualdad de la consulta. Estas restricciones no reducen el número de entradas de índice que escanea Firestore en el modo Datastore, pero filtran las entidades que no coinciden para que se reduzca el número de entidades que se devuelven a los clientes.

Para obtener más información sobre cómo crear índices eficientes, consulta Estructura y definición de índices y Optimizar índices.

Ordena las propiedades en orden decreciente de selectividad de la restricción de consulta

Para asegurarte de que Firestore en el modo de Datastore selecciona el índice óptimo para tu consulta, especifica una cláusula orderBy() que ordene las propiedades de intervalo y de desigualdad en función de lo selectivas que sean sus restricciones en tu consulta, empezando por la más selectiva. Una selectividad más alta coincide con menos entidades, mientras que una selectividad más baja coincide con más entidades. En el orden de tu índice, coloca las propiedades de intervalo y desigualdad con mayor selectividad antes de las propiedades con menor selectividad.

Para minimizar el número de entidades que Firestore en el modo de Datastore analiza y devuelve a través de la red, siempre debes ordenar las propiedades de mayor a menor selectividad de las restricciones de consulta. Si el conjunto de resultados no está en el orden requerido y se espera que sea pequeño, puede implementar una lógica del lado del cliente para reordenarlo según sus expectativas.

Por ejemplo, si quieres buscar en una colección de empleados a los que residen en Estados Unidos y cuyo salario es superior a 100.000 USD,y ordenar los resultados por los años de experiencia de los empleados. Si crees que solo un pequeño número de empleados tendrá un salario superior a 100.000 USD, una forma eficiente de escribir la consulta es la siguiente:

Java

Query<Entity> query =
  Query.newEntityQueryBuilder()
    .setKind("employees")
    .setFilter(PropertyFilter.gt("salary", 100000))
    .setOrderBy(OrderBy("salary"))
    .build();
QueryResults<Entity> results = datastore.run(query);
// Order results by `experience`

Node.js

const query = datastore
  .createQuery("employees")
  .filter(new PropertyFilter("salary", ">", 100000))
  .order("salary");
const [entities] = await datastore.runQuery(query);
// Order results by `experience`

Python

query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.order = ["salary"]
results = query.fetch()
// Order results by `experience`

Aunque añadir un orden a experience en la consulta dará como resultado el mismo conjunto de entidades y evitará que se vuelvan a ordenar los resultados en los clientes, la consulta puede leer muchas más entradas de índice extrañas que la consulta anterior. Esto se debe a que Firestore en el modo de Datastore siempre prefiere un índice cuyas propiedades de índice coincidan con el prefijo de la cláusula "order by" de la consulta. Si se añade experience a la cláusula "order by", Firestore en modo Datastore seleccionará el índice (experience [...], salary [...]) para calcular los resultados de la consulta. Como no hay otras restricciones en experience, Firestore en el modo de Datastore leerá todas las entradas de índice de la colección employees antes de aplicar el filtro salary para encontrar el conjunto de resultados final. Esto significa que las entradas de índice que no cumplen el filtro salary se siguen leyendo, lo que aumenta la latencia y el coste de la consulta.

Precios

Las consultas con filtros de intervalo y de desigualdad en varias propiedades se facturan en función de las entidades leídas y las entradas de índice leídas.

Para obtener información detallada, consulta la página Precios.

Limitaciones

Además de las limitaciones de las consultas, ten en cuenta las siguientes limitaciones antes de usar consultas con filtros de intervalo y de desigualdad en varias propiedades:

  • Para evitar que las consultas sean demasiado caras, Firestore en el modo de Datastore limita el número de operadores de intervalo o de desigualdad a 10.

Siguientes pasos