Beschreibung
Definieren Sie temporäre Variablen, auf die in nachfolgenden Phasen der Pipeline verwiesen werden kann.
Variablen, die in der let(...) Phase erstellt wurden, sind nicht in den Endergebnissen enthalten
es sei denn, sie werden in einer späteren Phase explizit einem Feld zugewiesen (z.B. mit
add_fields(...) oder
select(...)). So können Sie komplexe Logik vereinfachen, indem Sie sie in kleinere, wiederverwendbare Komponenten aufteilen, ohne die Ausgabedokumente zu überladen. Die Phase let(...) ist besonders nützlich für korrelierte
Unterpipelines, bei denen eine Unterpipeline auf einen Wert aus dem Bereich des übergeordneten
Dokuments verweisen muss.
Beispiele
Node.js
const results = await db.pipeline()
.collection("/awards")
// `let(...)` referred to as `define(...)` in the Web SDK.
.define(rand().as("r"))
.addFields(
switchOn(
lessThan(variable("r"), 0.05), constant("rare"),
lessThan(variable("r"), 0.25), constant("uncommon"),
constant("common")).as("random_score"))
.execute();
Verhalten
Variablen im Vergleich zu Feldern
Während Felder Daten darstellen, die in Dokumenten gespeichert sind, sind Variablen temporäre Werte, die nur während der Ausführung der Pipeline vorhanden sind.
| Felder | Variablen | |
|---|---|---|
| Zweck | Auf Felder in Dokumenten zugreifen oder sie dort speichern | Temporäre Werte während der Pipelineausführung generieren oder darauf zugreifen |
| SDK-Nutzung | field("name") |
variable("name") |
| Umfang | Lokal für das aktuelle Dokument | Global für Pipeline und Unterpipelines |
| Nicht definierte Referenzen | Wird zu absent ausgewertet |
Generiert Laufzeitfehler |
Umfang :
Während Felder auf das lokale Dokument beschränkt sind, werden Variablen in einem
separaten Bereich definiert und bleiben über Phasen hinweg zugänglich, bis die erste Phase erreicht wird, in der
mehrere Dokumente zusammengeführt werden (z. B.
aggregate(...) oder
distinct(...)). In Phasen, in denen mehrere
Dokumente zusammengeführt werden, können keine Variablenreferenzen mehr verwendet werden, da durch das Zusammenführen
der Ergebnisse der vorherigen Phase kein einzelner Wert mehr für die
Variable vorhanden ist.
Empfehlung: Verweisen Sie auf eine Variable, nachdem Sie die Felder des Dokuments gefiltert haben.
Node.js
const results = db.pipeline()
.collection("/awards")
.define(min(field("score").abs(), constant(100)).as("normalized_score"))
.select(field("__name__"), field("owner_id"))
// Successfully able to use the variable.
.where(variable("normalized_score").greaterThan(10))
.execute();
Nicht empfehlenswert: Verweisen Sie nach einer Aggregation nicht auf eine Variable.
Node.js
const results = db.pipeline()
.collection("/awards")
.define(min(field("score").abs(), constant(100)).as("normalized_score"))
.aggregate({
accumulators: [ field("score").avg().as("avg_score") ],
groups: [ field("owner_id") ]
})
// Attempting to use the variable throws a request validation error.
.where(variable("normalized_score").greaterThan(10))
.execute();
Nicht definierte Referenzen :
Während das Verweisen auf ein nicht definiertes Feld in Ordnung ist (und einfach zu absent ausgewertet wird), schlägt der Versuch, auf eine nicht definierte Variable zu verweisen, bei der Anfragevalidierung fehl. In diesem Sinne können Feldreferenzen als Suche in einer Map zur Laufzeit betrachtet werden, während Variablenreferenzen eher Variablen in einer statisch kompilierten Programmiersprache ähneln.
Globaler Bereich und Unterabfragen
Variablen sind unerlässlich, wenn Sie mit verschachtelten Pipelines arbeiten. Eine Unterpipeline wird in einem eigenen Bereich ausgeführt und kann nur auf die Felder der Dokumente zugreifen, die sie gerade verarbeitet. Wenn Sie einen Wert aus dem übergeordneten Dokument in einer Unterabfrage verwenden möchten, müssen Sie ihn zuerst mit der Phase let(...) als Variable definieren.
Node.js
// Fetch reviewers alongside their negative reviews.
const pipeline = db.pipeline()
.collection("/reviewers")
// `let(...)` referred to as `define(...)` in the Web SDK.
.define(field("__name__").as("reviewer_name"))
.select("__name__", array(db.pipeline().collectionGroup("reviews")
.where(field("author").equals(variable("reviewer_name")))
.where(field("rating").lessThan(2))
.select("review", "rating")).as("negative_reviews"))
.execute();
Überlappende Variablen
Wenn Sie eine Variable mit einem Namen definieren, der bereits in einer vorherigen Phase let(...) definiert wurde, wird die vorherige Variable überschrieben. So können Sie den temporären Status im Laufe der Pipeline aktualisieren.
Variablen, auf die in Unterpipelines verwiesen wird, folgen den Regeln für den lexikalischen Bereich , wie sie in vielen Programmiersprachen zu finden sind. Sie beziehen sich auf die Variablen unter dem selben Namen, die von der nächstgelegenen (übergeordneten) Pipeline definiert wurden.
Vergleich mit add_fields(...)
Die let(...) Phase verhält sich ähnlich wie die
add_fields(...) Phase. Anstatt jedoch
Felder zum Dokument hinzuzufügen, werden Variablen Werte zugewiesen.