Cloud Firestore поддерживает использование фильтров диапазона и неравенства для нескольких полей в одном запросе. Вы можете использовать условия диапазона и неравенства в нескольких полях и упростить разработку приложений, делегировав реализацию логики постфильтрации Cloud Firestore .
Фильтры диапазона и неравенства в нескольких полях
Следующий запрос использует фильтры диапазона по населению и плотности, чтобы вернуть все города, где население превышает 1 000 000 человек, а плотность населения составляет менее 10 000 человек на единицу площади.
Веб-версия 9 модульная
const q = query(
collection(db, "cities"),
where('population', '>', 1000000),
where('density', '<', 10000),
);
Быстрый
let query = db.collection("cities")
.whereField("population", isGreaterThan: 1000000)
.whereField("density", isLessThan: 10000)
Цель-C
FIRQuery *query =
[[[[self.db collectionWithPath:@"cities"]
queryWhereField:@"population" isGreaterThan:@1000000]
queryWhereField:@"density" isLessThan:@10000];
Ява Андроид
Query query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Котлин+KTX Android
val query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000)
Идти
query := client.Collection("cities").
Where("population", ">", 1000000).
Where("density", "<", 10000)
Ява
db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Node.js
db.collection("cities")
.where('population', '>', 1000000),
.where('density', '<', 10000)
Питон
from google.cloud import firestore
db = firestore.Client()
query = db.collection("cities")
.where("population", ">", 1000000)
.where("density", "<", 10000)
PHP
С#
Руби
query = cities_ref.where("population", ">", "1000000")
.where("density", "<", 10000)
С++
CollectionReference cities_ref = db->Collection("cities");
Query query = cities_ref.WhereGreaterThan("population", FieldValue::Integer(1000000))
.WhereLessThan("density", FieldValue::Integer(10000));
Единство
CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef.WhereGreaterThan("population", 1000000)
.WhereLessThan("density", 10000);
Дарт
final citiesRef = FirebaseFirestore.instance.collection('cities')
final query = citiesRef.where("population", isGreaterThan: 1000000)
.where("density", isLessThan: 10000);
Рекомендации по индексированию
Прежде чем выполнять запросы, прочтите о запросах и модели данных Cloud Firestore .
В Cloud Firestore предложение ORDER BY
запроса определяет, какие индексы могут использоваться для обслуживания запроса. Например, запрос ORDER BY a ASC, b ASC
требует составного индекса для полей a ASC, b ASC
.
Чтобы оптимизировать производительность и стоимость запросов Cloud Firestore , оптимизируйте порядок полей в индексе. Для этого убедитесь, что ваш индекс упорядочен слева направо, чтобы запрос перешел к набору данных, который предотвращает сканирование ненужных записей индекса.
Предположим, вы хотите выполнить поиск по коллекции сотрудников и найти сотрудников из США, чья зарплата превышает 100 000 долларов США, а количество лет опыта работы больше 0. Исходя из вашего понимания набора данных, вы знаете, что ограничение заработной платы является более избирательным. чем ограничение опыта. Идеальным индексом, который позволит сократить количество просмотров индекса, будет (salary [...], experience [...])
. Таким образом, запрос, который был бы быстрым и экономичным, будет упорядочивать salary
до experience
и выглядеть следующим образом:
Ява
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");
Питон
db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">", 0)
.order_by("salary")
.order_by("experience");
Лучшие практики по оптимизации индексов
При оптимизации индексов обратите внимание на следующие рекомендации.
Упорядочите поля индекса по равенствам, за которыми следует наиболее избирательный диапазон или поле неравенства.
Cloud Firestore использует самые левые поля составного индекса для удовлетворения ограничений равенства и ограничения диапазона или неравенства, если таковые имеются, в первом поле запроса orderBy()
. Эти ограничения могут уменьшить количество записей индекса, сканируемых Cloud Firestore . Cloud Firestore использует оставшиеся поля индекса для удовлетворения других ограничений диапазона или неравенства запроса. Эти ограничения не уменьшают количество записей индекса, которые сканирует Cloud Firestore , но отфильтровывают несовпадающие документы, чтобы уменьшить количество документов, возвращаемых клиентам.
Дополнительные сведения о создании эффективных индексов см. в разделе Свойства индекса .
Упорядочите поля в порядке убывания избирательности ограничений запроса.
Чтобы убедиться, что Cloud Firestore выберет оптимальный индекс для вашего запроса, укажите предложение orderBy()
, которое упорядочивает поля в порядке убывания избирательности ограничений запроса. Более высокая избирательность соответствует меньшему подмножеству документов, тогда как более низкая избирательность соответствует большему подмножеству документов. Убедитесь, что вы выбрали поля диапазона или неравенства с более высокой избирательностью раньше при упорядочивании индекса, чем поля с более низкой избирательностью.
Чтобы свести к минимуму количество документов, которые Cloud Firestore сканирует и возвращает по сети, всегда следует упорядочивать поля в порядке убывания избирательности ограничений запроса. Если набор результатов не находится в требуемом порядке и ожидается, что набор результатов будет небольшим, вы можете реализовать логику на стороне клиента, чтобы изменить его порядок в соответствии с вашими ожиданиями.
Например, предположим, что вы хотите выполнить поиск по коллекции сотрудников, чтобы найти сотрудников из США, чья зарплата превышает 100 000 долларов США, и упорядочить результаты по году опыта сотрудника. Если вы ожидаете, что лишь небольшое количество сотрудников будет иметь зарплату выше 100 000 долларов США, то наиболее эффективный способ написать запрос будет следующим:
Ява
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`
Питон
results = db.collection("employees")
.where("salary", ">", 100000)
.order_by("salary")
.stream()
// Order results by `experience`
Хотя добавление к запросу упорядочивания по experience
приведет к получению того же набора документов и предотвратит изменение порядка результатов на клиентах, запрос может прочитать гораздо больше посторонних записей индекса, чем предыдущий запрос. Это связано с тем, что Cloud Firestore всегда предпочитает индекс, префикс полей индекса которого соответствует предложению order by запроса. Если в предложение order by был добавлен experience
, Cloud Firestore выберет индекс (experience [...], salary [...])
для вычисления результатов запроса. Поскольку других ограничений на experience
нет, Cloud Firestore прочитает все записи индекса коллекции employees
, прежде чем применять фильтр salary
, чтобы найти окончательный набор результатов. Это означает, что записи индекса, которые не удовлетворяют фильтру salary
, все равно читаются, что увеличивает задержку и стоимость запроса.
Цены
Запросы с фильтрами диапазона и неравенства по нескольким полям оплачиваются на основе прочитанных документов и прочитанных записей индекса.
Подробную информацию смотрите на странице Цены .
Ограничения
Помимо ограничений запроса , обратите внимание на следующие ограничения перед использованием запросов с фильтрами диапазона и неравенства для нескольких полей:
- Запросы с фильтрами диапазона или неравенства в полях документа и только с ограничениями равенства для ключа документа
(__name__)
не поддерживаются. - Cloud Firestore ограничивает количество полей диапазона или неравенства до 10. Это сделано для того, чтобы запросы не становились слишком дорогими для выполнения.
Что дальше
- Узнайте об оптимизации запросов .
- Узнайте больше о выполнении простых и сложных запросов .
- Узнайте, как Cloud Firestore использует индексы .