Descrizione
Definisci le 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 ai campi o archiviarli nei documenti | generare o accedere a valori temporanei durante l'esecuzione della pipeline |
| Utilizzo dell'SDK | field("name") |
variable("name") |
| Ambito | locale per il documento corrente | globale per pipeline e sub-pipeline |
| Riferimenti non definiti | valore absent |
genera un errore di runtime |
Ambito:
Mentre i campi sono limitati al documento locale, le variabili vengono definite in un
ambito separato e rimangono accessibili nelle varie fasi fino alla prima occorrenza di
una fase che "unisce" più documenti (ad es.
aggregate(...) o
distinct(...)). Le fasi che "uniscono" più
documenti non consentono di utilizzare i riferimenti alle variabili in un secondo momento, perché unendo
i risultati della fase precedente non esiste più un solo valore per la
variabile.
Esegui: 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 eseguire: fai 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();
Riferimenti non definiti:
Sebbene sia possibile fare riferimento a un campo non definito (il valore è absent), 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 l'esecuzione di 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 subquery
Le variabili sono essenziali quando si lavora con le pipeline nidificate. Una sub-pipeline 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 subquery, 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. Questa operazione può essere utilizzata per aggiornare lo stato temporaneo man mano che la pipeline procede.
Le variabili a cui si fa riferimento nella sub-pipeline seguono le regole di ambito lessicale presenti 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.