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)
Java
db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Node.js
db.collection("cities")
.where('population', '>', 1000000),
.where('density', '<', 10000)
Python
from google.cloud import firestore
db = firestore.Client()
query = db.collection("cities")
.where("population", ">", 1000000)
.where("density", "<", 10000)
PHP
C#
Руби
query = cities_ref.where("population", ">", "1000000")
.where("density", "<", 10000)
C++
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 и выглядеть следующим образом:
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");
Передовые методы оптимизации индексов
При оптимизации индексов следует учитывать следующие рекомендации.
Упорядочить поля индекса по равенствам, а затем по наиболее избирательному диапазону или полю неравенства.
Cloud Firestore использует самые левые поля составного индекса для удовлетворения ограничений равенства и ограничений диапазона или неравенства, если таковые имеются, для первого поля запроса orderBy() . Эти ограничения могут уменьшить количество записей индекса, которые сканирует Cloud Firestore . Cloud Firestore использует оставшиеся поля индекса для удовлетворения других ограничений диапазона или неравенства запроса. Эти ограничения не уменьшают количество записей индекса, которые сканирует Cloud Firestore , но отфильтровывают несовпадающие документы, так что количество документов, возвращаемых клиентам, уменьшается.
Для получения более подробной информации о создании эффективных индексов см. раздел «Свойства индекса» .
Упорядочить поля в порядке убывания селективности ограничений запроса
Чтобы гарантировать, что Cloud Firestore выберет оптимальный индекс для вашего запроса, укажите условие orderBy() , которое упорядочивает поля в порядке убывания селективности ограничений запроса. Более высокая селективность соответствует меньшему подмножеству документов, а более низкая — большему. Убедитесь, что поля диапазона или неравенства с более высокой селективностью выбираются раньше в порядке упорядочивания индекса, чем поля с более низкой селективностью.
Чтобы минимизировать количество документов, которые Cloud Firestore сканирует и возвращает по сети, поля всегда следует упорядочивать в порядке убывания селективности ограничений запроса. Если результирующий набор не соответствует требуемому порядку и ожидается, что он будет небольшим, можно реализовать логику на стороне клиента для переупорядочивания в соответствии с вашими ожиданиями.
Например, предположим, вы хотите выполнить поиск по группе сотрудников в США, чья зарплата превышает 100 000 долларов, и отсортировать результаты по стажу работы сотрудника. Если вы ожидаете, что лишь небольшое количество сотрудников будет иметь зарплату выше 100 000 долларов, то наиболее эффективный способ сформулировать запрос будет следующим:
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`
Добавление параметра сортировки по experience к запросу даст тот же набор документов и позволит избежать повторной сортировки результатов на стороне клиента, однако запрос может прочитать гораздо больше лишних записей индекса, чем предыдущий запрос. Это связано с тем, что Cloud Firestore всегда предпочитает индекс, префикс полей которого соответствует предложению ORDER BY запроса. Если в предложение ORDER BY добавить параметр experience , Cloud Firestore выберет индекс (experience [...], salary [...]) для вычисления результатов запроса. Поскольку других ограничений на experience нет, Cloud Firestore прочитает все записи индекса коллекции employees , прежде чем применить фильтр salary для получения окончательного набора результатов. Это означает, что записи индекса, не удовлетворяющие фильтру salary , все равно будут прочитаны, что увеличит задержку и стоимость запроса.
Цены
Запросы с фильтрами по диапазону и неравенству по нескольким полям оплачиваются исходя из количества прочитанных документов и прочитанных записей в индексе.
Подробную информацию см. на странице «Цены» .
Ограничения
Помимо ограничений, связанных с самими запросами , перед использованием запросов с фильтрами по диапазону и неравенству по нескольким полям следует учитывать следующие ограничения:
- Запросы с фильтрами по диапазону или неравенству по полям документа и только ограничениями равенства по ключу документа
(__name__)не поддерживаются. - Cloud Firestore ограничивает количество полей диапазона или неравенства до 10. Это сделано для того, чтобы запросы не стали слишком ресурсоемкими в выполнении.
Что дальше?
- Узнайте об оптимизации ваших запросов .
- Узнайте больше о выполнении простых и составных запросов .
- Разберитесь, как Cloud Firestore использует индексы .