Descripción general de consultas con filtros de rango y desigualdad en varios campos
Firestore admite el uso de filtros de rango y desigualdad en varios campos de una sola consulta. Ahora puedes tener condiciones de rango y desigualdad en varios campos 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.
Filtros de rango y desigualdad en varios campos
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.
Modular de la versión web 9
const q = query(
collection(db, "users"),
where('age', '>', 35),
where('height', '>', 60),
where('height', '<', 70)
);
Swift
let query = db.collection("users")
.whereField("age", isGreaterThan: 35)
.whereField("height", isGreaterThan: 60)
.whereField("height", isLessThan: 70)
Objective-C
FIRQuery *query =
[[[[self.db collectionWithPath:@"users"]
queryWhereField:@"age" isGreaterThan:@35]
queryWhereField:@"height" isGreaterThan:@60]
queryWhereField:@"height" isLessThan:@70];
Android de Java
Query query = db.collection("users")
.whereGreaterThan("age", 35)
.whereGreaterThan("height", 60)
.whereLessThan("height", 70);
Kotlin+KTX para Android
val query = db.collection("users")
.whereGreaterThan("age", 35)
.whereGreaterThan("height", 60)
.whereLessThan("height", 70)
Java
db.collection("users")
.whereGreaterThan("age", 35)
.whereGreaterThan("height", 60)
.whereLessThan("height", 70);
Node.js
db.collection("users")
.where('age', '>', 35),
.where('height', '>', 60),
.where('height', '<', 70)
Consideraciones sobre la indexación
Antes de comenzar a ejecutar consultas, asegúrate de leer sobre las consultas y el modelo de datos de Firestore.
En Firestore, la cláusula ORDER BY
de una consulta determina qué índices se pueden usar para entregar la consulta. Por ejemplo, una consulta ORDER BY a ASC, b ASC
requiere un índice compuesto en los campos a ASC, b ASC
.
Para optimizar el rendimiento y el costo de las consultas de Firestore, debes optimizar el orden de los campos 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 (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:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Node.js
db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">", 0)
.orderBy("salary")
.orderBy("experience");
Python
db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">", 0)
.order_by("salary")
.order_by("experience");
Prácticas recomendadas para optimizar índices
Cuando optimices índices, ten en cuenta las siguientes prácticas recomendadas.
Ordena los campos de índice por igualdades seguidas del rango más selectivo o el campo de desigualdad
Firestore usa los campos de la izquierda de un índice compuesto para cumplir con las restricciones de igualdad y la restricción de rango o desigualdad, si corresponde, en el primer campo de la consulta orderBy()
. Estas restricciones pueden reducir la cantidad de entradas de índice
que Firestore analiza. Firestore usa los campos restantes del índice para satisfacer otras restricciones de rango o desigualdad de la consulta. Estas
restricciones no reducen la cantidad de entradas de índice que Firestore analiza,
sino que filtran los documentos no coincidentes para que se reduzca la cantidad de documentos
que se muestran a los clientes.
Para obtener más información sobre cómo crear índices eficientes, consulta la definición de un índice perfecto.
Ordena los campos en orden descendente de selectividad de la restricción de consulta
A fin de asegurarte de que Firestore seleccione el índice óptimo para tu consulta,
especifica una cláusula orderBy()
que ordene los campos en orden descendente de selectividad
de la restricción de consulta. Una selectividad más alta coincide con un subconjunto más pequeño de documentos, mientras que una más baja coincide con un subconjunto más grande de documentos. Asegúrate de seleccionar campos de rango o de desigualdad con mayor selectividad antes en el orden de índice que campos con una selectividad más baja.
Para minimizar la cantidad de documentos que Firestore analiza y muestra en la red, siempre debes ordenar los campos 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
db.collection("employees")
.whereGreaterThan("salary", 100000)
.orderBy("salary")
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
// Order results by `experience`
}
});;
Node.js
const querySnapshot = await db.collection('employees')
.where("salary", ">", 100000)
.orderBy("salary")
.get();
// Order results by `experience`
Python
results = db.collection("employees")
.where("salary", ">", 100000)
.order_by("salary")
.stream()
// Order results by `experience`
Si bien agregar un orden en experience
a la consulta generará el mismo conjunto
de documentos 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 siempre prefiere un índice cuyo prefijo de campos de índice coincida con la cláusula ordenar por de la consulta. Si se agregó experience
a la cláusula ordenar por,
Firestore seleccionará el índice (experience [...], salary [...])
para calcular los resultados de las consultas. Debido a que no hay otras restricciones en
experience
, Firestore 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 varios campos se facturan según la lectura de documentos 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 varios campos:
- No se admiten las consultas con filtros de rango o desigualdad en los campos de documentos y solo restricciones
de igualdad en la clave del documento
(__name__)
. - Firestore limita la cantidad de rangos o campos de desigualdad a 10. Esto sirve para evitar que las consultas sean demasiado costosas para ejecutarse.
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 usa índices.