Descripción general de consultas con filtros de rango y desigualdad en varias propiedades

Firestore en modo Datastore admite el uso de filtros de rango y desigualdad en varias propiedades en una sola consulta. Ahora puedes tener condiciones de rango y desigualdad en varias propiedades y simplificar el desarrollo de tu aplicación mediante la delegación de la implementación de la lógica posterior al filtrado a Firestore en modo Datastore.

Filtros de rango y desigualdad en varias propiedades

La siguiente consulta muestra todos los usuarios cuya edad es mayor que 35 y altura entre 60 y 70 años usando los filtros de rango de edad y altura.

GQL

 SELECT * FROM /users WHERE age > 35 AND height > 60 AND height < 70;

Java


  Query<Entity> query =
    Query.newEntityQueryBuilder()
      .setKind("users")
      .setFilter(
        CompositeFilter.and(
            PropertyFilter.gt("age", 35), PropertyFilter.gt("height", 60), PropertyFilter.lt("height", 70)))
    .build();

Consideraciones sobre la indexación

Antes de comenzar a ejecutar consultas, asegúrate de que leíste la información sobre las consultas.

Si no se especifica una cláusula ORDER BY, Firestore en modo Datastore usa cualquier índice que pueda cumplir con la condición del filtro de la consulta para entregar la consulta, lo que produce un conjunto de resultados que se ordena según la definición del índice.

Para optimizar el rendimiento y el costo de las consultas de Firestore en modo Datastore, debes optimizar el orden de las propiedades en el índice. Para ello, debes asegurarte de que tu índice esté ordenado de izquierda a derecha, de modo que la consulta se transfiera a un conjunto de datos que evite el análisis de entradas de índice irrelevantes.

Supongamos que deseas buscar en un grupo de empleados y encontrar aquellos cuyo salario sea superior a 100,000 y cuya cantidad de años de experiencia sea mayor que 0. Según tu comprensión del conjunto de datos, sabes que la restricción salarial es más selectiva que la restricción de experiencia. El índice ideal que reduciría la cantidad de análisis de índices sería el índice (salary [...], experience [...]). Por lo tanto, la consulta que sería rápida y rentable ordenaría salary antes que experience y se vería de la siguiente manera:

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

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

Ordena las consultas por igualdades seguidas del rango más selectivo o el campo de desigualdad

Firestore en modo Datastore usa las propiedades que se encuentran más a la izquierda de un índice compuesto para satisfacer las restricciones de igualdad y la restricción de rango y desigualdad, si corresponde, en el primer campo de la consulta orderBy(). Estas restricciones pueden reducir la cantidad de entradas de índice que analiza Firestore en modo Datastore. Firestore en modo Datastore usa las propiedades restantes del índice para satisfacer otras restricciones de rango y desigualdad de la consulta. Estas restricciones no reducen la cantidad de entradas de índice que Firestore en modo Datastore analiza, pero filtran las entidades no coincidentes para que se reduzca la cantidad de entidades que se muestran a los clientes.

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

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

Para asegurarte de que Firestore en modo Datastore seleccione el índice óptimo para tu consulta, especifica una cláusula orderBy() que ordene las propiedades de rango y desigualdad en orden descendente de selectividad de restricción de consulta. Una selectividad más alta coincide con un subconjunto más pequeño de entidades, mientras que una más baja coincide con un subconjunto más grande de entidades. Asegúrate de seleccionar propiedades de rango y desigualdad con mayor selectividad antes en el orden de índice que las propiedades con selectividad baja.

Para minimizar la cantidad de entidades que Firestore en modo Datastore analiza y muestra en la red, siempre debes ordenar las propiedades en orden descendente de selectividad de la restricción de consulta. Si el conjunto de resultados no está en el orden requerido y se espera que el conjunto de resultados sea pequeño, puedes implementar la lógica del cliente para reordenarlo según tu expectativa de orden.

Por ejemplo, supongamos que deseas realizar una búsqueda en un grupo de empleados para encontrar aquellos cuyo salario sea superior a 100,000 y ordenar los resultados por año de experiencia del empleado. Si esperas que solo una pequeña cantidad de empleados tenga un salario superior a 100,000, entonces la forma más 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`

Si bien agregar un orden en experience a la consulta generará el mismo conjunto de entidades y evitará el reordenamiento de 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 modo Datastore siempre prefiere un índice cuyo prefijo de propiedades de índice coincida con la cláusula ordenar por de la consulta. Si se agregó experience a la cláusula ordenar por, Firestore en modo Datastore seleccionará el índice (experience [...], salary [...]) para calcular los resultados de las consultas. Debido a que no hay otras restricciones en experience, Firestore en modo 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 satisfacen el filtro salary se leen de todos modos, lo que aumenta la latencia y el costo de la consulta.

Precios

Las consultas con filtros de rango y desigualdad en varias propiedades se facturan según la lectura de entidades y las entradas de índice.

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

Limitaciones

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

  • Firestore en modo Datastore limita la cantidad de operadores de rango o desigualdad a 10. Esto sirve para evitar que las consultas sean demasiado costosas para ejecutarse.

Pasos siguientes