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)
Objective-C
FIRQuery *query =
[[[[self.db collectionWithPath:@"cities"]
queryWhereField:@"population" isGreaterThan:@1000000]
queryWhereField:@"density" isLessThan:@10000];
Java Android
Query query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Kotlin+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 использует индексы .