Przegląd zapytań z filtrami zakresów i nierówności w wielu polach

Cloud Firestore obsługuje korzystanie z filtrów zakresów i nierówności w wielu polach w jednym zapytaniu. Możesz teraz stosować warunki dotyczące zakresów i niejakości w wielu polach oraz uprościć tworzenie aplikacji dzięki delegowaniu implementacji logiki postfiltrowania do Cloud Firestore.

Filtry zakresów i nierówności w wielu polach

To zapytanie zwróci wszystkich użytkowników, którzy mają wiek powyżej 35 lat i wzrost między 60 a 70. Korzystamy z filtrów zakresów dla wieku i wzrostu.

Modułowa wersja internetowa 9

  const q = query(
      collection(db, "users"),
      where('age', '>', 35),
      where('height', '>', 60),
      where('height', '<', 70)
    );

Swift

 let query = db.collection("users")
   .whereField("age", isGreaterThan: 35)
   .whereField("height", isGreaterThan: 60)
   .whereField("height", isLessThan: 70)

Objective-C

 FIRQuery *query = 
  [[[[self.db collectionWithPath:@"users"]
 queryWhereField:@"age" isGreaterThan:@35]
    queryWhereField:@"height" isGreaterThan:@60] 
        queryWhereField:@"height" isLessThan:@70];

Android w Javie

 Query query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70);

Kotlin + KTX – Android

 val query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70)

Java

  db.collection("users")
    .whereGreaterThan("age", 35)
    .whereGreaterThan("height", 60)
    .whereLessThan("height", 70);

Node.js

db.collection("users")
  .where('age', '>', 35),
  .where('height', '>', 60),
  .where('height', '<', 70)

Uwagi na temat indeksowania

Zanim zaczniesz wykonywać zapytania, zapoznaj się z zapytaniami i modelem danych Cloud Firestore.

W Cloud Firestore klauzula ORDER BY zapytania określa indeksy, których można użyć do obsługi zapytania. Na przykład zapytanie ORDER BY a ASC, b ASC wymaga złożonego indeksu w polach a ASC, b ASC.

Aby zoptymalizować wydajność i koszty zapytań do Cloud Firestore, warto zoptymalizować kolejność pól w indeksie. Aby to zrobić, sprawdź, czy indeks jest uporządkowany od lewej do prawej, tak aby zapytanie było oczyszczane do postaci zbioru danych, który uniemożliwia skanowanie wpisów indeksów nadmiarowych.

Załóżmy, że chcesz przeszukać zbiór pracowników i znaleźć pracowników, których pensja przekracza 1 000 000 lat, a doświadczenie – większe niż 0. Z Twojego zrozumienia zbioru danych wynika, że ograniczenie wynagrodzenia jest bardziej selektywne niż ograniczenie związane z doświadczeniem. Idealny indeks, który zmniejszyłby liczbę skanowań indeksu, to (salary [...], experience [...]). Dlatego zapytanie, które jest szybkie i ekonomiczne, zamówiłoby salary przed experience i wyglądałoby 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 stosuj te sprawdzone metody.

Uporządkuj pola indeksu według równości, po których następuje najbardziej selektywny zakres lub pole nierówności

Cloud Firestore używa skrajnych pól indeksu złożonego po lewej stronie, aby spełnić ograniczenia równości oraz ewentualne ograniczenie zakresu lub nierówności w pierwszym polu zapytania orderBy(). Te ograniczenia mogą zmniejszyć liczbę wpisów 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 skanowanych przez Cloud Firestore, ale odfiltrowują niedopasowane dokumenty, co zmniejsza liczbę dokumentów zwracanych klientom.

Aby uzyskać więcej informacji na temat tworzenia wydajnych indeksów, zapoznaj się z definicją indeksu idealnego.

Uporządkuj pola w malejącej kolejności 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ń zapytań. Większa selektywność oznacza dopasowanie do mniejszego podzbioru dokumentów, a mniejsza – do większego podzbioru dokumentów. Pamiętaj, aby podczas ustalania kolejności indeksów wybrać pola zakresu lub nierówności o większej selektywności niż pola o niższej selektywności.

Aby zminimalizować liczbę dokumentów, które Cloud Firestore skanuje i zwraca przez sieć, należy zawsze porządkować pola w kolejności malejącej selektywności ograniczeń zapytań. Jeśli zbiór wyników nie ma wymaganej kolejności, a zbiór wyników powinien być mały, możesz zaimplementować logikę po stronie klienta, aby zmienić kolejność wyników zgodnie z oczekiwaniami.

Załóżmy, że chcesz przeszukać zbiór pracowników, aby znaleźć pracowników, których wynagrodzenie wynosi ponad 1 000 000, i uporządkować wyniki według roku doświadczenia pracownika. Jeśli spodziewasz się, że tylko niewielka liczba pracowników otrzyma wynagrodzenie powyżej 1 000 000, najwydajniejszym sposobem utworzenia zapytania jest następujący sposób:

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 kolejności w polu experience spowoduje uzyskanie tego samego zestawu dokumentów i zakłóci zmianę kolejności wyników na klientach, ale zapytanie może odczytywać o wiele więcej zbędnych wpisów indeksu niż wcześniejsze zapytanie. Wynika to z tego, że Cloud Firestore zawsze preferuje indeks, którego prefiks pól indeksu pasuje do klauzuli kolejności według klauzuli zapytania. Jeśli do zamówienia według klauzuli dodano experience, Cloud Firestore wybierze indeks (experience [...], salary [...]) do obliczania wyników zapytań. Ponieważ w tabeli experience nie ma żadnych innych ograniczeń, Cloud Firestore odczyta wszystkie wpisy indeksu w kolekcji employees, zanim zastosuje filtr salary w celu znalezienia ostatecznego zbioru wyników. Oznacza to, że wpisy indeksu, które nie spełniają warunków filtra salary, są nadal odczytywane, co zwiększa czas oczekiwania i koszt zapytania.

Ceny

Zapytania z filtrami zakresów i nierówności w wielu polach są rozliczane na podstawie przeczytanych dokumentów i odczytanych wpisów indeksu.

Szczegółowe informacje znajdziesz na stronie Ceny.

Ograniczenia

Zanim użyjesz zapytań z filtrami zakresu i nierówności w wielu polach, oprócz ograniczeń dotyczących zapytań weź pod uwagę te ograniczenia:

  • Zapytania z filtrami zakresu lub nierówności w polach dokumentu i tylko ograniczenia równości w kluczu dokumentu (__name__) nie są obsługiwane.
  • Cloud Firestore ogranicza liczbę pól zakresu lub nierówności do 10. Dzięki temu zapytania nie będą zbyt kosztowne do uruchomienia.

Co dalej