Firestore en modo Datastore admite el uso de filtros de rango y desigualdad en varias propiedades de una sola consulta. Esta función te brinda condiciones de rango y desigualdad en varias propiedades y simplifica el desarrollo de tu aplicación, ya que delega 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 usa filtros de rango para la prioridad y los días para mostrar 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 comenzar a ejecutar consultas, asegúrate de haber leído sobre las consultas.
Si no se especifica una cláusula ORDER BY
, Firestore en modo Datastore usa cualquier índice que
pueda satisfacer la condición del filtro de la consulta para entregarla. Este enfoque 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, optimiza el orden de las propiedades en el índice. Para ello, asegúrate de que tu índex esté ordenado de izquierda a derecha para que la consulta se extraiga en 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 para encontrar empleados de Estados Unidos cuyo salario es superior a USD 100,000 y cuya cantidad de años de experiencia es mayor que 0. En función de tu comprensión del conjunto de datos, sabes que la restricción salarial es más selectiva que la limitación de la experiencia. Un índice que reduce la cantidad de análisis del índice es el
índice (salary [...], experience [...])
. Como resultado, una consulta rápida y
rentable ordena 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 í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 más a la izquierda de un índice compuesto para satisfacer
las restricciones de igualdad y la restricción de rango o desigualdad, si las hay, en el
primer campo de la consulta orderBy()
. Estas restricciones pueden reducir la cantidad de
entradas de índice que Firestore en modo Datastore analiza. 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 analiza Firestore en modo Datastore, pero filtran las entidades no coincidentes para que se reduzca la cantidad de entidades que se devuelven a los clientes.
Para obtener más información sobre cómo crear índices eficientes, consulta la estructura y la definición de los índices y cómo optimizar los í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 según
qué tan selectivas sean sus restricciones en tu consulta, comenzando por la más
selectiva. Una mayor selectividad coincide con menos entidades, mientras que una selectividad más baja
coincide con más entidades. En el ordenamiento del índice, coloca las propiedades de rango y desigualdad
con una selectividad más alta antes de las propiedades con una selectividad más baja.
Para minimizar la cantidad de entidades que Firestore en modo Datastore analiza y devuelve a la red, siempre debes ordenar las propiedades en orden descendente según la selectividad de las restricciones de la consulta. Si el conjunto de resultados no está en el orden requerido y el conjunto de resultados esperados es pequeño, puedes implementar la lógica del cliente y volver a hacer el pedido según lo previsto.
Por ejemplo, si quieres buscar en una colección de empleados para encontrar empleados de Estados Unidos cuyo salario es superior a USD 100,000 y ordenar los resultados por años de experiencia del empleado. Si esperas que solo una pequeña cantidad de empleados tenga un salario superior a $100,000, 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`
Si bien agregar un orden en experience
a la consulta generará el mismo conjunto
de entidades y omitirá 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 el
orden por cláusula de la consulta. Si experience
se agregara al orden por una cláusula,
entonces Firestore en modo Datastore seleccionará el índice (experience [...], salary [...])
para procesar los resultados de las consultas. Como 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. Esto significa que las entradas de índice que no satisfacen el filtro salary
aún se leen, 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 en función de las entidades y las entradas de índice leídas.
Para obtener más detalles, consulta la página de precios.
Limitaciones
Además de las limitaciones de las consultas, ten en cuenta las siguientes limitaciones antes de usar las consultas con filtros de rango y desigualdad en varias propiedades:
- Para evitar que las consultas sean demasiado costosas de ejecutar, Firestore en modo Datastore limita la cantidad de operadores de rango o desigualdad a 10.
Pasos siguientes
- Obtén información para optimizar tus consultas.
- Obtén más información para realizar consultas simples y compuestas.
- Comprende cómo Firestore en modo Datastore usa índices.