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

Cloud Firestore obsługuje używanie filtrów zakresów i nierówności w wielu polach w jednym zapytaniu. Możesz podać warunki zakresu i nierówności w wielu polach, programowaniu aplikacji przez przekazanie implementacji logiki postfiltrowania do: i Cloud Firestore.

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

To zapytanie korzysta z filtrów zakresów dotyczących populacji i gęstości, aby zwrócić wszystkie miasta z liczbą zaludnienia i liczbą zaludnienia przekraczającą 1 000 000 to mniej niż 10 000 osób na jednostkę powierzchni.

Modułowa wersja internetowa 9

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];

Android w Javie

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

$collection = $db->collection('samples/php/cities');
$chainedQuery = $collection
    ->where('population', '>', 1000000)
    ->where('density', '<', 10000);

C#

CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef
    .WhereGreaterThan("Population", 1000000)
    .WhereLessThan("Density", 10000);
QuerySnapshot querySnapshot = await query.GetSnapshotAsync();
foreach (DocumentSnapshot documentSnapshot in querySnapshot)
{
    var name = documentSnapshot.GetValue<string>("Name");
    var population = documentSnapshot.GetValue<int>("Population");
    var density = documentSnapshot.GetValue<int>("Density");
    Console.WriteLine($"City '{name}' returned by query. Population={population}; Density={density}");
}

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 na temat indeksowania

Przed uruchomieniem zapytań przeczytaj zapytania i model danych Cloud Firestore.

W Cloud Firestore klauzula ORDER BY zapytania określa, które indeksy . 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ń do Cloud Firestore, zoptymalizować kolejność pól w indeksie. W tym celu upewnij się, że indeks w kolejności od lewej do prawej, tak aby zapytanie było przekształcane do zbioru danych, zapobiega skanowaniu zbędnych wpisów indeksu.

Załóżmy, że chcesz przeszukać zbiór pracowników i znaleźć Stany Zjednoczone. pracowników,których wynagrodzenie wynosi ponad 100 000 USD i ma wieloletnie doświadczenie większy niż 0. Z Twojego zrozumienia zbioru danych wynika, że ograniczenie zarobków jest bardziej selektywne niż ograniczenie doświadczenia. Idealna który ograniczy liczbę skanowań indeksu, (salary [...], experience [...]) Zatem zapytanie, które byłoby szybkie o opłacalnej wartości zamówienia salary przed experience 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 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ć wymagania ograniczenia równości oraz ograniczenie zakresu lub nierówności, jeśli występuje, w pierwszym polu zapytania orderBy(). Te ograniczenia mogą zmniejszyć liczbę indeksów Wpisy skanowane przez Cloud Firestore. Cloud Firestore używa pozostałych pól indeksu, aby spełnić inne ograniczenia dotyczące zakresu lub nierówności zapytania. Te ograniczenia nie zmniejszają liczby wpisów indeksu skanowanych przez Cloud Firestore ale odfiltrowuje niedopasowane dokumenty, by zmniejszyć ich liczbę wraca do klienta.

Więcej informacji o tworzeniu wydajnych indeksów znajdziesz w artykule o właściwościach indeksowania.

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 malejącej kolejności w zapytaniu selektywność ograniczenia. Większa selektywność pasuje do mniejszego podzbioru dokumentów. Mniejsza selektywność odpowiada większego podzbioru dokumentów. Upewnij się, że wcześniej wybierasz pola zakresu lub nierówności o większej selektywności. niż pola o mniejszej selektywności.

Aby zminimalizować liczbę dokumentów, które Cloud Firestore skanuje i zwraca Kolejność pól należy zawsze ułożyć w kolejności malejącej selektywność ograniczenia. Jeśli wyniki nie są ujęte w wymaganej kolejności, a makro zbiór wyników powinien być mały, możesz zaimplementować funkcje logiczne po stronie klienta, zmień je zgodnie z oczekiwaniami.

Załóżmy, że chcesz przeszukać zbiór pracowników, aby znaleźć Pracownicy z USA, których wynagrodzenie przekracza 100 000 USD, i porządkują wyniki według roku z doświadczeniem pracownika. Jeśli spodziewasz się, że tylko niewielka liczba pracowników będzie otrzymywać wynagrodzenia powyżej 100 000 USD, 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 wyświetlenie tego samego zbioru dokumentów i uniknąć zmiany kolejności wyników w klientach, zapytanie może odczytuje znacznie więcej zbędnych wpisów indeksu niż wcześniejsze zapytanie. Dzieje się tak, ponieważ Cloud Firestore zawsze preferuje indeks, którego prefiks pól indeksu pasuje do kolejność według klauzuli zapytania. Jeśli do zamówienia dodano klauzulę experience, Cloud Firestore wybierze indeks (experience [...], salary [...]). do przetwarzania wyników zapytań. Ponieważ nie ma innych ograniczeń experience, Cloud Firestore będzie odczytywać wszystkie wpisy indeksu employees przed zastosowaniem filtra salary w celu znalezienia ostatecznej wartości wyniki. Oznacza to, że wpisy indeksu, które nie spełniają warunków salary nadal są odczytywane, co zwiększa czas oczekiwania i koszty zapytania.

Ceny

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

Szczegółowe informacje znajdziesz na stronie Ceny.

Ograniczenia

Oprócz ograniczeń dotyczących zapytań pamiętaj o opisanych niżej ograniczeniach, za pomocą zapytań z filtrami zakresów i nierówności w wielu polach:

  • Zapytania z filtrami zakresów lub nierówności w polach dokumentu i tylko o równości ograniczenia dotyczące klucza 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 drogie do uruchomienia.

Co dalej?