Übersicht: Abfrage mit Bereichs- und Ungleichheitsfiltern für mehrere Felder
In Firestore können Bereichs- und Ungleichheitsfilter für mehrere Felder in einer einzigen Abfrage verwendet werden. 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.
Webversion 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 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
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));
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);
Überlegungen zur Indexierung
Lesen Sie sich die Informationen zu Abfragen und zum Firestore-Datenmodell durch, bevor Sie Ihre Abfragen ausführen.
In Firestore wird mit der ORDER BY
-Klausel einer Abfrage festgelegt, welche Indexe für die Ausführung der Abfrage verwendet werden können. 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. Achten Sie dabei darauf, dass der Index von links nach rechts sortiert ist, damit die Abfrage zu einem Datensatz führt, der das Scannen unnötiger Indexeinträge verhindert.
Angenommen, Sie möchten in einer Sammlung von Mitarbeitern nach Mitarbeitern in den USA suchen, deren Gehalt über 100.000 $ liegt und deren Berufserfahrung mehr als 0 Jahre beträgt. Aus Ihrer Kenntnis des Datensatzes wissen Sie, dass die Gehaltsbeschränkung selektiver ist als die Erfahrungsbeschränkung. Das ideale
der die Anzahl der Indexscans reduzieren würde, wäre der
(salary [...], experience [...])
Eine schnelle und kosteneffiziente Abfrage würde salary
also vor experience
sortieren und 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.
Indexfelder nach Gleichheitsbedingungen sortieren, gefolgt vom selektivsten Bereichs- oder Ungleichheitsfeld
Firestore verwendet die Felder links im zusammengesetzten Index, um die Gleichheitsbeschränkungen und gegebenenfalls die Bereichs- oder Ungleichheitsbeschränkung für das erste Feld der orderBy()
-Abfrage zu erfüllen. Diese Einschränkungen können die Anzahl der
Einträge, die Firestore scannt. Firestore verwendet die verbleibenden Felder des Index, um andere Bereichs- oder Ungleichheitsbeschrä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 Indexeigenschaften.
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. Eine höhere Selektivität entspricht einer kleineren Teilmenge von Dokumenten, während eine niedrigere Selektivität einer größeren Teilmenge von Dokumenten entspricht. Achten Sie darauf, dass Sie Bereichs- oder Ungleichheitsfelder mit höherer Selektivität früher in der Indexsortierung auswählen als Felder mit niedrigerer Selektivität.
Um die Anzahl der Dokumente zu minimieren, die von Firestore über das Netzwerk gescannt und zurückgegeben werden, sollten Sie Felder immer in absteigender Reihenfolge der Selektivität der Abfrageeinschränkung anordnen. 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 in einer Gruppe von Mitarbeitern nach Mitarbeitern in den USA suchen, deren Gehalt über 100.000 $ liegt, und die Ergebnisse nach Berufsjahren sortieren. 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, dass Firestore immer einen Index bevorzugt, dessen Indexfeldpräfix mit der Order-by-Klausel der Abfrage übereinstimmt. Wenn experience
der Sortierklausel hinzugefügt wurde, wählt Firestore den Index (experience [...], salary [...])
zum Berechnen der Abfrageergebnisse aus. 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.
Weitere Informationen finden Sie auf der Seite Preise.
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 Gleichheitsbeschrä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
- Informationen zum Optimieren von Abfragen
- Weitere Informationen zum Ausführen einfacher und zusammengesetzter Abfragen
- Informationen zur Verwendung von Indexen in Firestore