Cloud Firestore obsługuje stosowanie filtrów zakresu i nierówności do wielu pól w jednym zapytaniu. Możesz stosować warunki zakresu i nierówności w wielu polach oraz uprościć tworzenie aplikacji, delegując implementację logiki po filtrowaniu do funkcji Cloud Firestore.
Filtry zakresu i nierówności na wielu polach
Zapytanie to używa filtrów zakresu dotyczących populacji i gęstości zaludnienia,aby zwrócić wszystkie miasta,w których populacja jest większa niż 1 000 000 osób,a gęstość zaludnienia jest mniejsza niż 10 000 osób na jednostkę powierzchni.
Wersja internetowa 9 modular
const q = query(
collection(db, "cities"),
where('population', '>', 1000000),
where('density', '<', 10000),
);
Swift
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 na Androida
Query query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Kotlin + KTX na Androidzie
val query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000)
Go
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#
Ruby
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));
Unity
CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef.WhereGreaterThan("population", 1000000)
.WhereLessThan("density", 10000);
Dart
final citiesRef = FirebaseFirestore.instance.collection('cities')
final query = citiesRef.where("population", isGreaterThan: 1000000)
.where("density", isLessThan: 10000);
Uwagi dotyczące indeksowania
Zanim uruchomisz zapytania, zapoznaj się z informacjami o zapytaniach i modelu danych Cloud Firestore.
W Cloud Firestore klauzula ORDER BY
zapytania określa, które indeksy mogą być używane do obsługi zapytania. Na przykład zapytanie ORDER BY a ASC, b ASC
wymaga indeksu złożonego na polach a ASC, b ASC
.
Aby zoptymalizować wydajność i koszt zapytań Cloud Firestore, zoptymalizuj kolejność pól w indeksie. Aby to zrobić, sprawdź, czy indeks jest uporządkowany od lewej do prawej, tak aby zapytanie prowadziło do zbioru danych, który zapobiega skanowaniu niepotrzebnych wpisów indeksu.
Załóżmy, że chcesz przeszukać zbiory pracowników i znaleźć tych w Stanach Zjednoczonych, których wynagrodzenie przekracza 100 tys. USD, a ich doświadczenie zawodowe jest dłuższe niż 0 lat. Na podstawie swoich obserwacji dotyczących zbioru danych wiesz, że ograniczenie dotyczące wynagrodzenia jest bardziej selektywne niż ograniczenie dotyczące doświadczenia. Idealnym indeksem, który zmniejszyłby liczbę skanowań indeksu, byłby (salary [...], experience [...])
. Dlatego zapytanie, które będzie szybkie i wydajne kosztowo, będzie porządkować salary
przed experience
i będzie wyglądać tak:
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");
Sprawdzone metody optymalizacji indeksów
Podczas optymalizowania indeksów pamiętaj o tych sprawdzonych metodach.
Sortowanie pól indeksu według równań, a następnie według najbardziej selektywnego zakresu lub pola nierówności
Zapytanie Cloud Firestore używa pól znajdujących się najdalej w lewą stronę indeksu złożonego, aby spełnić ograniczenia równości i zakresu lub ograniczenia nierówności (jeśli występują) w przypadku pierwszego pola zapytania orderBy()
. Te ograniczenia mogą zmniejszyć liczbę indeksowanych pozycji, które Cloud Firestore skanuje. Cloud Firestore używa pozostałych pól indeksu do zaspokajania innych ograniczeń zakresu lub nierówności zapytania. Te ograniczenia nie zmniejszają liczby pozycji indeksu, które Cloud Firestoreskanuje, ale odfiltrowują niepasujące dokumenty, dzięki czemu zmniejsza się liczba dokumentów zwracanych klientom.
Więcej informacji o tworzeniu wydajnych indeksów znajdziesz w artykule Właściwości indeksu.
Polecenia sortowania pól według malejącej selektywności ograniczeń zapytań
Aby zapytanie Cloud Firestore wybierało optymalny indeks, określ klauzulę orderBy()
, która porządkuje pola w malejącym porządku selektywności ograniczeń zapytania. Większa selektywność oznacza dopasowanie do mniejszego podzbioru dokumentów, a mniejsza – do większego podzbioru dokumentów. Pamiętaj, aby wybierać pola zakresu lub nierówności o większej selektywności wcześniej w porządku indeksu niż pola o mniejszej selektywności.
Aby zminimalizować liczbę dokumentów, które Cloud Firestoreskanuje i zwraca w sieci, zawsze należy uporządkować pola w malejącym porządku selektywności ograniczeń zapytań. Jeśli zbiór wyników nie jest uporządkowany w wymaganej kolejności i oczekujesz, że zbiór wyników będzie mały, możesz zastosować logikę po stronie klienta, aby uporządkować go zgodnie z Twoimi oczekiwaniami.
Załóżmy na przykład, że chcesz przeszukać kolekcję pracowników, aby znaleźć tych, którzy zarabiają ponad 100 tys. USD i mają co najmniej 10 lat doświadczenia. Wyniki możesz posortować według liczby lat doświadczenia pracownika. Jeśli spodziewasz się,że tylko niewielka liczba pracowników będzie miała pensje powyżej 100 tys. USD, najskuteczniejszym sposobem sformułowania zapytania będzie:
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`
Dodanie do zapytania sortowania według experience
spowoduje zwrócenie tego samego zbioru dokumentów i wyeliminuje konieczność ponownego sortowania wyników na klientach, ale zapytanie może odczytać znacznie więcej nieistotnych wpisów indeksu niż poprzednie zapytanie. Dzieje się tak, ponieważ Cloud Firestore zawsze preferuje indeks, którego prefiks pól indeksu pasuje do klauzuli order by zapytania. Jeśli do klauzuli order by dodano kolumnę experience
, funkcja Cloud Firestore wybierze indeks (experience [...], salary [...])
do obliczenia wyników zapytania. Ponieważ nie ma żadnych innych ograniczeń dotyczących zapytania experience
, przed zastosowaniem filtra salary
, aby znaleźć ostateczny zbiór wyników, funkcja Cloud Firestore odczyta wszystkie wpisy indeksu w kolekcji employees
. Oznacza to, że wpisy indeksu, które nie spełniają kryterium salary
filtru, są nadal odczytywane, co zwiększa opóźnienie i koszt zapytania.
Ceny
Zapytania z filtrami zakresu i nierówności w wielu polach są rozliczane na podstawie odczytanych dokumentów i odczytanych wpisów w indeksie.
Szczegółowe informacje znajdziesz na stronie Ceny.
Ograniczenia
Zanim użyjesz zapytań z filtrami zakresu i nierówności w kilku polach, pamiętaj o tych ograniczeniach (oprócz ograniczeń dotyczących zapytań):
- Zapytania z filtrami zakresu lub nierówności w polach dokumentu oraz tylko ograniczeniami równości w kluczu dokumentu
(__name__)
nie są obsługiwane. - Cloud Firestore ogranicza liczbę pól zakresu lub nierówności do 10. Ma to zapobiec zbyt wysokim kosztom zapytań.
Co dalej?
- Dowiedz się więcej o optymalizowaniu zapytań.
- Dowiedz się więcej o wykonaniu prostych i złożonych zapytań.
- Dowiedz się, jak Cloud Firestore korzysta z indeksów.