Beschreibung
Filtert die Dokumente aus der vorherigen Phase und gibt nur die Dokumente zurück, für die die Bedingung true ergibt.
Beispiele
Web
let results; results = await execute(db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) ); results = await execute(db.pipeline().collection("books") .where(and(field("rating").equal(5), field("published").lessThan(1900))) );
Swift
var results: Pipeline.Snapshot results = try await db.pipeline().collection("books") .where(Field("rating").equal(5)) .where(Field("published").lessThan(1900)) .execute() results = try await db.pipeline().collection("books") .where(Field("rating").equal(5) && Field("published").lessThan(1900)) .execute()
Kotlin
var results: Task<Pipeline.Snapshot> results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute() results = db.pipeline().collection("books") .where(Expression.and(field("rating").equal(5), field("published").lessThan(1900))) .execute()
Java
Task<Pipeline.Snapshot> results; results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute(); results = db.pipeline().collection("books") .where(Expression.and( field("rating").equal(5), field("published").lessThan(1900) )) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import And, Field results = ( client.pipeline() .collection("books") .where(Field.of("rating").equal(5)) .where(Field.of("published").less_than(1900)) .execute() ) results = ( client.pipeline() .collection("books") .where(And(Field.of("rating").equal(5), Field.of("published").less_than(1900))) .execute() )
Java
Pipeline.Snapshot results1 = firestore .pipeline() .collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute() .get(); Pipeline.Snapshot results2 = firestore .pipeline() .collection("books") .where(and(field("rating").equal(5), field("published").lessThan(1900))) .execute() .get();
Go
results1, err := client.Pipeline(). Collection("books"). Where(firestore.FieldOf("rating").Equal(5)). Where(firestore.FieldOf("published").LessThan(1900)). Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err } results2, err := client.Pipeline(). Collection("books"). Where(firestore.And( firestore.FieldOf("rating").Equal(5), firestore.FieldOf("published").LessThan(1900), )). Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err }
Verhalten
Verkettete und geschachtelte Filter
Mehrere where(...)-Phasen können verkettet werden. Das ist logisch gleichwertig mit dem Kombinieren der Filterbedingungen in einer einzelnen where(...)-Phase mit einem and(...)-Ausdruck. Beide Ansätze führen zum gleichen Ausführungsplan und haben keine Auswirkungen auf die Ausführung oder Leistung von Abfragen.
Beispiel: Mehrere where(...)-Phasen verketten:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.where(field("location.country").equals("USA"))
.where(field("population").greaterThan(500000))
.execute();
entspricht der Verwendung einer einzelnen where(...)-Phase mit einem zusammengesetzten and(...):
Node.js
const cities = await db.pipeline()
.collection("/cities")
.where(
field("location.country").equals("USA")
.and(field("population").greaterThan(500000)))
.execute();
Das Filtern auf Grundlage eines logischen or(...) von Bedingungen kann jedoch nicht auf mehrere Phasen aufgeteilt werden und muss in einer einzelnen where(...)-Phase erfolgen:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.where(
field("location.state").equals("NY")
.or(field("location.state").equals("CA")))
.execute();
Komplexe Ausdrücke
Die Filterbedingung kann komplexe Filterbedingungen mit tief verschachtelten Ausdrücken und logischen Operatoren enthalten. Beispiel:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.where(
field("name").like("San%")
.or(
field("location.state").charLength().greaterThan(7)
.and(field("location.country").equals("USA"))))
filtert /cities anhand eines regulären Ausdrucks oder wenn sich die Stadt in USA mit einem ausreichend langen Namen des Bundesstaats befindet. Als Bedingung kann ein beliebiger Ausdruck angegeben werden. Es werden jedoch nur die Elemente berücksichtigt, die true ergeben.
Reihenfolge der Phasen
Die Reihenfolge der Phasen ist wichtig, da sie die Reihenfolge der Abfrageauswertung ändern kann. Beispiel:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.limit(10)
.where(field("location.country").equals("USA"))
.execute();
wird nur für location.country eine (potenziell zufällige) Gruppe von 10 Dokumenten gefiltert, da in der vorherigen Phase limit(...) die Dokumente eingeschränkt werden, die jemals für die Phase where(...) bereitgestellt werden. Daher gilt die Faustregel, die where(...)-Phasen so früh wie möglich in die Abfrage einzufügen.
HAVING-ähnliche Funktionen:
Die Phase where(...) kann nach jeder Phase erfolgen, in der das Schema der Dokumente geändert wird, z. B. select(...) oder aggregate(...). Sie bezieht sich auf die Felder, die in diesen Phasen erstellt werden. Wichtig für aggregate(...): Eine nachfolgende where(...)-Anweisung, die sich auf die kumulierten Felder bezieht, verhält sich wie eine HAVING-Anweisung in einem typischen SQL-System. Beispiel:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate({
accumulators: [field("population").sum().as("total_population")],
groups: ["location.state"]
})
.where(field("total_population").greaterThan(10000000))
Ermöglicht die Rückgabe der Bundesstaaten, in denen Städte mit einer bestimmten Gesamtbevölkerungsgröße vorhanden sind.