Cloud Firestore umożliwia używanie filtrów zakresu i nierówności w wielu polach w jednym zapytaniu. Możesz stosować warunki zakresu i nierówności w przypadku wielu pól oraz uprościć tworzenie aplikacji, delegując implementację logiki filtrowania końcowego do Cloud Firestore.
Filtry zakresu i nierówności w wielu polach
To zapytanie 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 (modułowa)
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 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)
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, przeczytaj informacje o zapytaniach i Cloud Firestore modelu danych.
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 w polach a ASC, b ASC
.
Aby zoptymalizować wydajność i koszty zapytań Cloud Firestore, zoptymalizuj kolejność pól w indeksie. Aby to zrobić, upewnij się, że indeks jest uporządkowany od lewej do prawej, tak aby zapytanie ograniczało się do zbioru danych, który uniemożliwia skanowanie niepotrzebnych wpisów indeksu.
Załóżmy, że chcesz przeszukać zbiór pracowników i znaleźć pracowników ze Stanów Zjednoczonych, których wynagrodzenie przekracza 100 tys. USD, a liczba lat doświadczenia jest większa niż 0. Na podstawie swojej wiedzy o zbiorze danych wiesz, że ograniczenie dotyczące wynagrodzenia jest bardziej selektywne niż ograniczenie dotyczące doświadczenia. Idealny indeks, który zmniejszyłby liczbę skanów indeksu, to (salary [...], experience [...])
. Dlatego zapytanie, które będzie szybkie i opłacalne, będzie zawierać 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 optymalizacji indeksów pamiętaj o tych sprawdzonych metodach.
Uporządkuj pola indeksu według równości, a następnie według najbardziej selektywnego zakresu lub pola nierówności.
Cloud Firestore używa pól najbardziej po lewej stronie indeksu złożonego, aby spełnić ograniczenia równości oraz ograniczenia zakresu lub nierówności (jeśli takie istnieją) w pierwszym polu zapytania orderBy()
. Te ograniczenia mogą zmniejszyć liczbę pozycji indeksu skanowanych przez Cloud Firestore. Cloud Firestore używa pozostałych pól indeksu, aby spełnić inne ograniczenia zakresu lub nierówności zapytania. Te ograniczenia nie zmniejszają liczby wpisów indeksu, które skanuje Cloud Firestore, ale odfiltrowują niedopasowane 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.
Uporządkuj pola w kolejności malejącej selektywności ograniczenia zapytania.
Aby mieć pewność, że Cloud Firestore wybierze optymalny indeks dla Twojego zapytania, określ klauzulę orderBy()
, która porządkuje pola w kolejności malejącej selektywności ograniczeń zapytania. Większa selektywność dopasowuje mniejszy podzbiór dokumentów, a mniejsza selektywność dopasowuje większy podzbiór dokumentów. Upewnij się, że pola zakresu lub nierówności o wyższej selektywności są wybierane wcześniej w kolejności indeksu niż pola o niższej selektywności.
Aby zminimalizować liczbę dokumentów, które Cloud Firestore skanuje i zwraca w sieci, zawsze sortuj pola w kolejności malejącej selektywności ograniczeń zapytania. Jeśli zestaw wyników nie jest w wymaganej kolejności i oczekuje się, że będzie mały, możesz zaimplementować logikę po stronie klienta, aby zmienić jego kolejność zgodnie z oczekiwaniami.
Załóżmy na przykład, że chcesz przeszukać zbiór pracowników, aby znaleźć pracowników ze Stanów Zjednoczonych, których wynagrodzenie przekracza 100 tys. USD, i posortować wyniki według lat doświadczenia pracownika. Jeśli spodziewasz się,że tylko niewielka liczba pracowników będzie zarabiać więcej niż 100 000 USD, najskuteczniejszy sposób na napisanie zapytania jest następujący:
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 klauzuli ORDER BY experience
spowoduje zwrócenie tego samego zestawu dokumentów i wyeliminuje konieczność ponownego sortowania wyników na klientach, ale zapytanie może odczytać znacznie więcej zbędnych wpisów indeksu niż poprzednie zapytanie. Dzieje się tak, ponieważ Cloud Firestore zawsze preferuje indeks, którego pola indeksu mają prefiks pasujący do klauzuli order by zapytania. Jeśli do klauzuli ORDER BY dodano experience
,Cloud Firestore wybierze indeks (experience [...], salary [...])
do obliczania wyników zapytania. Ponieważ nie ma innych ograniczeń dotyczących experience
, usługa Cloud Firestore odczyta wszystkie wpisy indeksu kolekcji employees
przed zastosowaniem filtra salary
w celu znalezienia ostatecznego zestawu wyników. Oznacza to, że wpisy indeksu, które nie spełniają warunków filtra salary
, są nadal odczytywane, co zwiększa czas oczekiwania na odpowiedź na zapytanie i jego koszt.
Ceny
Zapytania z filtrami zakresu i nierówności w wielu polach są rozliczane na podstawie odczytanych dokumentów i odczytanych wpisów indeksu.
Szczegółowe informacje znajdziesz na stronie Cennik.
Ograniczenia
Oprócz ograniczeń zapytań przed użyciem zapytań z filtrami zakresu i nierówności w wielu polach zwróć uwagę na te ograniczenia:
- Zapytania z filtrami zakresu lub nierówności w polach dokumentu i 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 uruchamiania zapytań.
Co dalej?
- Dowiedz się więcej o optymalizacji zapytań.
- Dowiedz się więcej o wykonywaniu prostych i złożonych zapytań.
- Dowiedz się, jak Cloud Firestore korzysta z indeksów.