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 en una sola consulta. Ahora puedes tener rango y condiciones de desigualdad en múltiples campos y simplificar tu desarrollo de aplicaciones delegando la implementación de la lógica de posfiltrado a Firestore
Filtros de rango y desigualdad en varios campos
La siguiente consulta devuelve todos los usuarios cuya edad es mayor de 35 años y la altura entre 60 y 70 usando los filtros de rango para la edad y la 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];
Java Android
Query query = db.collection("users")
.whereGreaterThan("age", 35)
.whereGreaterThan("height", 60)
.whereLessThan("height", 70);
Kotlin+KTX 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 tus 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
y cómo se puede 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 hacer lo siguiente: optimizar el orden de los campos en el índice. Para ello, debes asegurarte de que tu índice 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.
Supongamos que deseas buscar en un grupo de empleados y encontrar
empleados cuyo salario sea superior a 100,000 y cuya cantidad de años de experiencia sea
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. El índice ideal que reduciría la cantidad de análisis del índice sería
(salary [...], experience [...])
. Por lo tanto, la consulta que sería rápida y
rentable ordenaría salary
antes del 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 que se encuentran más a la izquierda de un índice compuesto para cumplir con la
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 conversiones
las entradas que Firestore analiza. Firestore usa los campos restantes
del índice para satisfacer otras restricciones de rango o desigualdad de la consulta. Estos
no reducen la cantidad de entradas de índice que Firestore analiza
pero excluye los documentos no coincidentes para que la cantidad de documentos que se
que se devuelven 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, haz lo siguiente:
especificar una cláusula orderBy()
que ordene los campos en orden de consulta descendente
selectividad de las restricciones. Una mayor selectividad coincide con un subconjunto más pequeño de
documentos, mientras que la selectividad más baja coincide con un subconjunto más grande de documentos. Asegúrate de
seleccionar campos de rango o de desigualdad con una selectividad más alta en el ordenamiento del índice antes
que los campos con una selectividad más baja.
Minimizar la cantidad de documentos que Firestore analiza y muestra en siempre debes ordenar los campos en orden descendente de consulta selectividad de las restricciones. 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, supongamos que deseas buscar en un grupo de empleados para encontrar empleados cuyo salario sea superior a 100,000 y ordenar los resultados por años de experiencia del empleado. Si esperas que solo un pequeño número de empleados tenga un salario mayor de 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`
Aunque agregar un orden en experience
a la consulta generará el mismo conjunto
de documentos y omitirá el reordenamiento de los resultados en los clientes, la consulta
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
orden por cláusula de la consulta. Si se agregaran experience
a la cláusula order by,
Luego, Firestore seleccionará el índice (experience [...], salary [...])
para procesar los resultados de la consulta. Como no hay otras limitaciones en
experience
, Firestore leerá todas las entradas de índice del
employees
antes de aplicar el filtro salary
para encontrar la colección final
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 varios campos se facturan en función de documentos y 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 varios campos:
- Consultas con filtros de rango o desigualdad en campos de documentos y solo igualdad
no se admiten restricciones en la clave del documento
(__name__)
. - Firestore limita la cantidad de campos de rango o desigualdad a 10. Esto sirve para evitar que las consultas sean demasiado costosas cuando se ejecuten.
Pasos siguientes
- Obtén información para optimizar tus consultas.
- Obtén más información para realizar consultas simples y compuestas.
- Obtén información sobre cómo Firestore usa índices.