Cloud 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 die Anwendungsentwicklung vereinfachen, indem Sie die Implementierung der Logik für die Nachfilterung an Cloud Firestore delegieren.
Bereichs- und Ungleichheitsfilter für mehrere Felder
Die folgende Abfrage verwendet Bereichsfilter für „population“ (Bevölkerung) und „density“ (Dichte), um alle Städte zurückzugeben, in denen die Bevölkerung über 1.000.000 liegt und die Bevölkerungsdichte unter 10.000 Personen pro Flächeneinheit liegt.
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 Android
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
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
Bevor Sie Ihre Abfragen ausführen, lesen Sie die Informationen zu Abfragen und zum Cloud Firestore Datenmodell.
In Cloud Firestore bestimmt die ORDER BY-Klausel einer Abfrage, welche Indexe
zum Ausführen der Abfrage verwendet werden können. Für eine Abfrage wie ORDER BY a ASC, b ASC ist beispielsweise ein zusammengesetzter Index für die Felder a ASC, b ASC erforderlich.
Um die Leistung und die Kosten von Cloud Firestore Abfragen, optimieren Sie die Reihenfolge der Felder im Index. Dazu muss der Index von links nach rechts so sortiert sein, dass die Abfrage auf ein Dataset beschränkt wird, das 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. Basierend auf Ihrem Wissen über das Dataset wissen Sie, dass die Gehaltsbeschränkung selektiver ist als die Beschränkung der Berufserfahrung. Der ideale Index, der die Anzahl der Indexscans reduzieren würde, wäre (salary [...], experience [...]). Die Abfrage, die schnell und kostengünstig wäre, würde salary 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 und dann nach dem selektivsten Bereichs- oder Ungleichheitsfeld sortieren
Cloud Firestore verwendet die Felder ganz links in einem zusammengesetzten Index, um die Gleichheitsbedingungen und die Bereichs- oder Ungleichheitsbedingung (falls vorhanden) für das erste Feld der orderBy() Abfrage zu erfüllen. Diese Bedingungen können die Anzahl der Index
einträge reduzieren, die von Cloud Firestore gescannt werden. Cloud Firestore verwendet die verbleibenden Felder
des Index, um andere Bereichs- oder Ungleichheitsbedingungen der Abfrage zu erfüllen. Diese
Bedingungen reduzieren nicht die Anzahl der Indexeinträge, die von Cloud Firestore gescannt werden,
filtern aber nicht übereinstimmende Dokumente heraus, sodass die Anzahl der Dokumente, die an die Clients zurückgegeben werden,
reduziert wird.
Weitere Informationen zum Erstellen effizienter Indexe finden Sie unter Indexeigenschaften.
Felder in absteigender Reihenfolge der Selektivität der Abfragebeschränkung sortieren
Damit Cloud Firestore den optimalen Index für Ihre Abfrage auswählt, geben Sie eine orderBy() Anweisung an, die Felder in absteigender Reihenfolge der Abfragebeschränkungsspezifität sortiert. 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 Cloud Firestore gescannt und über das Netzwerk zurückgegeben werden, sollten Sie Felder immer in absteigender Reihenfolge der Selektivität der Abfrage beschränkung sortieren. Wenn die Ergebnismenge nicht in der gewünschten Reihenfolge ist und die Ergebnismenge voraussichtlich klein ist, können Sie clientseitige Logik implementieren, um sie nach Ihren Erwartungen neu zu sortieren.
Angenommen, Sie möchten in einer Sammlung von Mitarbeitern nach Mitarbeitern in den USA suchen, deren Gehalt über 100.000 $ liegt, und die Ergebnisse nach der Berufserfahrung des Mitarbeiters sortieren. Wenn Sie davon ausgehen,dass nur eine kleine Anzahl von Mitarbeitern ein Gehalt von über 100.000 $ hat, ist die folgende Abfrage die effizienteste:
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 Sortierung nach experience hinzufügen, erhalten Sie zwar dieselbe Menge an Dokumenten und müssen die Ergebnisse nicht auf den Clients neu sortieren, aber die Abfrage liest möglicherweise viel mehr unnötige Indexeinträge als die vorherige Abfrage. Das liegt daran, dass
Cloud Firestore immer einen Index bevorzugt, dessen Indexfelder mit der
Reihenfolge der `ORDER BY`-Klausel der Abfrage übereinstimmen. Wenn experience der `ORDER BY`-Klausel hinzugefügt wird,
wählt Cloud Firestore den Index (experience [...], salary [...]) aus,
um die Abfrageergebnisse zu berechnen. Da es keine anderen Einschränkungen für
experience, Cloud Firestore liest alle Indexeinträge der Sammlung
employees, bevor der Filter salary angewendet wird, um die endgültige
Ergebnismenge zu ermitteln. Das bedeutet, dass Indexeinträge, die den Filter salary nicht erfüllen, trotzdem gelesen werden, was die Latenz und die Kosten der Abfrage erhöht.
Preise
Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Felder werden basierend auf den gelesenen Dokumenten und Indexeinträgen in Rechnung gestellt.
Weitere Informationen finden Sie auf der Preisseite.
Beschränkungen
Neben den Abfragebeschränkungen sollten Sie die folgenden Beschränkungen beachten, bevor Sie Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Felder verwenden:
- Abfragen mit Bereichs- oder Ungleichheitsfiltern für Dokumentfelder und nur Gleichheitsbedingungen für den Dokumentschlüssel
(__name__)werden nicht unterstützt. - Cloud Firestore beschränkt die Anzahl der Bereichs- oder Ungleichheitsfelder auf 10. Dadurch soll verhindert werden, dass Abfragen zu teuer werden.
Nächste Schritte
- Informationen zum Optimieren von Abfragen
- Weitere Informationen zum Ausführen einfacher und komplexer Abfragen.
- Informationen zur Verwendung von Indexen in Cloud Firestore in Cloud Firestore