Opis
Definiowanie zmiennych tymczasowych, do których można się odwoływać na kolejnych etapach potoku.
Zmienne utworzone na etapie let(...) nie są uwzględniane w wynikach końcowych
chyba że zostaną wyraźnie przypisane do pola na późniejszym etapie (np. za pomocą
add_fields(...) lub
select(...)). Umożliwia to uproszczenie złożonej logiki przez
podzielenie jej na mniejsze komponenty, które można ponownie wykorzystać, bez zaśmiecania dokumentów wyjściowych. Etap let(...) jest szczególnie przydatny w przypadku skorelowanych
podpotoków, w których podpotok musi odwoływać się do wartości z zakresu dokumentu nadrzędnego.
Przykłady
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();
Zachowanie
Zmienne a pola
Pola reprezentują dane przechowywane w dokumentach, a zmienne to wartości tymczasowe, które istnieją tylko podczas wykonywania potoku.
| Pola | Zmienne | |
|---|---|---|
| Cel | uzyskiwanie dostępu do pól w dokumentach i ich przechowywanie | generowanie wartości tymczasowych i uzyskiwanie do nich dostępu podczas wykonywania potoku |
| Korzystanie z pakietu SDK | field("name") |
variable("name") |
| Zakres | lokalny dla bieżącego dokumentu | globalny dla potoku i podpotoków |
| Niezdefiniowane odwołania | przyjmuje wartość absent |
generuje błąd środowiska wykonawczego |
Zakres:
Pola są ograniczone do dokumentu lokalnego, a zmienne są definiowane w
osobnym zakresie i pozostają dostępne na wszystkich etapach aż do pierwszego wystąpienia
etapu, który "łączy" ze sobą wiele dokumentów (np.
aggregate(...) lub
distinct(...)). Etapy, które "łączą" ze sobą wiele
dokumentów, nie pozwalają na późniejsze używanie odwołań do zmiennych, ponieważ przez połączenie
wyników poprzedniego etapu nie ma już jednej wartości zmiennej.
Zrób: odwołaj się do zmiennej po odfiltrowaniu pól dokumentu.
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();
Nie rób: nie odwołuj się do zmiennej po agregacji.
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();
Niezdefiniowane odwołania:
Odwoływanie się do niezdefiniowanego pola jest dopuszczalne (i po prostu przyjmuje wartość absent), ale próba odwołania się do niezdefiniowanej zmiennej zakończy się niepowodzeniem podczas weryfikacji żądania. W tym sensie odwołania do pól można traktować jako wyszukiwanie w mapie w czasie działania, a odwołania do zmiennych są bardziej podobne do zmiennych w statycznie kompilowanym języku programowania.
Zakres globalny i podzapytania
Zmienne są niezbędne podczas pracy z zagnieżdżonymi potokami. Podpotok jest wykonywany w swoim własnym zakresie i może uzyskiwać dostęp tylko do pól dokumentów, które aktualnie przetwarza. Aby użyć wartości z dokumentu „nadrzędnego” w podzapytaniu, musisz najpierw zdefiniować ją jako zmienną za pomocą etapu 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();
Nakładające się zmienne
Zdefiniowanie zmiennej o nazwie, która została już zdefiniowana na poprzednim etapie let(...), spowoduje zastąpienie poprzedniej zmiennej. Można to wykorzystać do aktualizowania stanu tymczasowego w miarę postępu potoku.
Zmienne, do których odwołuje się podpotok, są zgodne z regułami zakresu leksykalnego , które występują w wielu językach programowania, i odnoszą się do zmiennych o tej samej nazwie zdefiniowanych przez najbliższy (nadrzędny) potok.
Porównanie z add_fields(...)
Etap let(...) działa podobnie do etapu
add_fields(...), ale zamiast dodawać
pola do dokumentu, przypisuje wartości do zmiennych.