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

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

Bereichs- und Ungleichheitsfilter für mehrere Felder

Die folgende Abfrage gibt alle Nutzer zurück, deren Alter größer als 35 und ihre Größe zwischen 60 und 70 liegt, und zwar mithilfe von Bereichsfiltern nach Alter und Größe.

Web Version 9 modular

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

Java für Android

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

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

Hinweise zur Indexierung

Bevor Sie Ihre Abfragen ausführen, sollten Sie sich 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, sollten Sie um die Reihenfolge der Felder im Index zu optimieren. Dazu müssen Sie darauf achten, dass Ihr Index von links bis sodass die Abfrage ein Dataset enthält, das das Scannen von Daten verhindert, überflüssige Indexeinträge.

Angenommen, Sie möchten eine Gruppe von Mitarbeitern durchsuchen und Mitarbeitende, deren Gehalt mehr als 100.000 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 Die Definition eines perfekten Index.

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 Mitarbeitenden durchsuchen, Mitarbeitenden, deren Gehalt mehr als 100.000 beträgt, und sortieren die Ergebnisse nach Jahr die Erfahrung der Mitarbeitenden. Wenn Sie davon ausgehen, dass nur eine kleine Anzahl von Mitarbeitenden ein Gehalt 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.

Weitere Informationen