Descrizione
Definisci variabili temporanee a cui è possibile fare riferimento nelle fasi successive della pipeline.
Le variabili create nella fase let(...) non sono incluse nei risultati finali
a meno che non vengano assegnate esplicitamente a un campo in una fase successiva (ad es. utilizzando
add_fields(...) o
select(...)). In questo modo puoi semplificare la logica complessa
suddividendola in componenti più piccoli e riutilizzabili senza ingombrare i documenti di output. La fase let(...) è particolarmente utile per le sub-pipeline correlate, in cui una sub-pipeline deve fare riferimento a un valore dell'ambito del documento principale.
Esempi
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();
Comportamento
Variabili e campi
Mentre i campi rappresentano i dati archiviati nei documenti, le variabili sono valori temporanei che esistono solo durante l'esecuzione della pipeline.
| Campi | Variabili | |
|---|---|---|
| Finalità | accedere o archiviare campi nei documenti | generare o accedere a valori temporanei durante l'esecuzione della pipeline |
| Utilizzo dell'SDK | field("name") |
variable("name") |
| Ambito | locale al documento corrente | globale a pipeline e pipeline secondarie |
| Riferimenti non definiti | restituisce absent |
genera un errore di runtime |
Ambito:
Mentre i campi sono limitati al documento locale, le variabili sono definite in un ambito separato e rimangono accessibili nelle varie fasi fino alla prima occorrenza di una fase che "unisce" più documenti (come aggregate(...) o distinct(...)). Le fasi che "uniscono" più documenti non consentono di utilizzare i riferimenti alle variabili in un secondo momento, in quanto unendo i risultati della fase precedente non esiste più un valore per la variabile.
Azione: fai riferimento a una variabile dopo aver filtrato i campi del documento.
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();
Non: fare riferimento a una variabile dopo un'aggregazione.
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();
Undefined References:
Il riferimento a un campo non definito è accettabile (e viene valutato come absent),
ma il tentativo di fare riferimento a una variabile non definita non andrà a buon fine durante la convalida della richiesta. In questo senso, i riferimenti ai campi possono essere considerati come una ricerca
in una mappa in fase di runtime, mentre i riferimenti alle variabili sono più simili alle variabili in un
linguaggio di programmazione compilato staticamente.
Ambito globale e sottoquery
Le variabili sono essenziali quando si lavora con pipeline nidificate. Una pipeline secondaria
viene eseguita nel proprio ambito e può accedere solo ai campi dei documenti che sta
elaborando. Per utilizzare un valore del documento "principale" all'interno di una
sottoquery, devi prima definirlo come variabile utilizzando la fase let(...).
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();
Variabili sovrapposte
La definizione di una variabile con un nome già definito in una fase
let(...) precedente sovrascriverà la variabile precedente. Può essere utilizzato per
aggiornare lo stato temporaneo man mano che la pipeline procede.
Le variabili a cui viene fatto riferimento nella pipeline secondaria seguono le regole di ambito lessicale che si trovano in molti linguaggi di programmazione e si riferiscono alle variabili con lo stesso nome definite dalla pipeline più vicina (principale).
Confronto con add_fields(...)
La fase let(...) si comporta in modo simile alla fase
add_fields(...), ma anziché aggiungere
campi al documento, assegna valori alle variabili.