Abfrage mit Bereichs- und Ungleichheitsfiltern für mehrere Felder – Übersicht

Firestore unterstützt die Verwendung von Bereichs- und Ungleichheitsfiltern für mehrere Felder in einer einzelnen Abfrage. Sie können Bereichs- und Ungleichheitsbedingungen für mehrere Felder festlegen und Ihre indem Sie die Implementierung der Nachfilterungslogik an Firestore

Bereichs- und Ungleichheitsfilter für mehrere Felder

Bei der folgenden Abfrage werden Bereichsfilter für Grundgesamtheit und Dichte verwendet, um alle Städte mit mehr als 1.000.000 Einwohnern und Bevölkerungsdichten weniger als 10.000 Personen pro Flächeneinheit.

Web Version 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 für Android

Query query = db.collection("cities")
 .whereGreaterThan("population", 1000000)
 .whereLessThan("density", 10000);

Kotlin+KTX für 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));

Einheit

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

Hinweise zur Indexierung

Bevor Sie Abfragen ausführen, lesen Sie zu Abfragen und zum Firestore-Datenmodell

In Firestore bestimmt die ORDER BY-Klausel einer Abfrage, welche Indexe die für die Abfrage verwendet werden kann. Beispiel: Eine ORDER BY a ASC, b ASC-Abfrage erfordert einen zusammengesetzten Index für die a ASC, b ASC-Felder.

Um die Leistung und Kosten von Firestore-Abfragen zu optimieren, um die Reihenfolge der Felder im Index zu optimieren. Stellen Sie dazu sicher, dass Ihr Index von links nach rechts sortiert, sodass die Abfrage ein Dataset ergibt, verhindert das Scannen unnötiger Indexeinträge.

Angenommen, Sie möchten eine Ansammlung von Mitarbeitern in den USA durchsuchen. Mitarbeitende,deren Gehalt mehr als 100.000 US-Dollar beträgt und deren Erfahrung größer als 0 ist. Basierend auf Ihrem Verständnis des Datasets wissen Sie, dass das Gehaltsbeschränkung ist selektiver als die Erfahrungsbeschränkung. Das ideale der die Anzahl der Indexscans reduzieren würde, wäre der (salary [...], experience [...]) Die schnelle und schnelle Abfrage salary vor experience bestellen und dann so aussehen:

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");

Best Practices für die Optimierung von Indexen

Beachten Sie beim Optimieren von Indexen die folgenden Best Practices.

Sortiere Indexfelder nach Gleichheit, gefolgt vom selektivesten Bereich oder Ungleichheitsfeld

Firestore verwendet die Felder ganz links eines zusammengesetzten Index, um die Gleichheitseinschränkungen und ggf. den Bereich oder Ungleichheitseinschränkung für das erste Feld der orderBy()-Abfrage. Diese Einschränkungen können die Anzahl der Einträge, die Firestore scannt. Firestore verwendet die verbleibenden Felder des Index, um andere Bereichs- oder Ungleichheitseinschränkungen der Abfrage zu erfüllen. Diese Einschränkungen verringern nicht die Anzahl der Indexeinträge, die von Firestore gescannt werden Sie filtern nicht übereinstimmende Dokumente heraus, sodass die Anzahl der Dokumente, zurückgegeben werden.

Weitere Informationen zum Erstellen effizienter Indexe finden Sie unter Indexattribute.

Felder in absteigender Reihenfolge der Auswahl der Abfrageeinschränkung sortieren

Damit Firestore den optimalen Index für Ihre Abfrage auswählt, Sie geben eine orderBy()-Klausel an, die Felder in absteigender Reihenfolge der Abfrage anordnet zur Auswahl der Einschränkungsselektivität. Höhere Selektivität stimmt mit einer kleineren Teilmenge von Dokumente, während eine niedrigere Selektivität auf eine größere Anzahl von Dokumenten zutrifft. Stellen Sie sicher, dass Sie wählen Bereichs- oder Ungleichheitsfelder mit höherer Selektivität früher im Index aus. als Felder mit geringer Selektivität.

Um die Anzahl der Dokumente zu minimieren, die Firestore scannt und über die sie zurückgegeben wird sollten Sie die Felder immer in absteigender Reihenfolge zur Auswahl der Einschränkungsselektivität. Wenn die Ergebnismenge nicht in der erforderlichen Reihenfolge liegt und der erwartet wird, dass die Ergebnismenge klein ist, können Sie clientseitige Logik implementieren, und bestell ihn entsprechend deinen Erwartungen neu.

Angenommen, Sie möchten eine Gruppe von Mitarbeitern durchsuchen, US-Mitarbeitenden, deren Gehalt mehr als 100.000 US-Dollar beträgt, und sortieren die Ergebnisse nach Jahr die Erfahrung der Mitarbeitenden. Wenn Sie davon ausgehen, dass nur eine kleine Anzahl von Mitarbeitenden Gehälter hat größer als 100.000 $ist, lässt sich die Abfrage so am effizientesten schreiben:

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`

Wenn Sie der Abfrage eine experience-Reihenfolge hinzufügen, erhalten Sie den gleichen Satz. und eine Neuanordnung der Ergebnisse bei der Kundschaft vermeidet, kann die Abfrage viel mehr irrelevante Indexeinträge lesen als die vorherige Abfrage. Das liegt daran, Firestore bevorzugt immer einen Index, dessen Präfix für Indexfelder mit dem Klausel der Abfrage. Wurden der Klausel „Order by“ experience hinzugefügt, wählt Firestore den Index (experience [...], salary [...]) aus. zur Berechnung von Abfrageergebnissen. Da es keine anderen Einschränkungen experience, wird Firestore alle Indexeinträge der employees aus, bevor Sie den Filter salary anwenden, um das endgültige Ergebnismenge. Das bedeutet, dass Indexeinträge, die die salary nicht erfüllen, Filter immer noch gelesen, wodurch sich die Latenz und die Kosten der Abfrage erhöhen.

Preise

Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Felder werden basierend auf gelesene Dokumente und gelesene Indexeinträge.

Ausführliche Informationen finden Sie auf der Preisseite.

Beschränkungen

Abgesehen von den Abfrageeinschränkungen müssen Sie folgende Einschränkungen beachten, Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Felder verwenden:

  • Abfragen mit Bereichs- oder Ungleichheitsfiltern für Dokumentfelder und nur für Gleichheitsfilter Einschränkungen für den Dokumentschlüssel (__name__) werden nicht unterstützt.
  • Firestore begrenzt die Anzahl der Bereichs- oder Ungleichheitsfelder auf 10. Damit soll verhindert werden, dass Abfragen zu teuer werden. ausgeführt werden soll.

Nächste Schritte