Deskripsi
Tentukan variabel sementara yang dapat dirujuk pada tahap selanjutnya dari pipeline.
Variabel yang dibuat di tahap let(...) tidak disertakan dalam hasil akhir kecuali jika ditetapkan secara eksplisit ke kolom di tahap berikutnya (misalnya, menggunakan add_fields(...) atau select(...)). Dengan demikian, Anda dapat menyederhanakan logika yang kompleks dengan memecahnya menjadi komponen yang lebih kecil dan dapat digunakan kembali tanpa membuat dokumen output menjadi berantakan. Tahap let(...) sangat berguna untuk sub-pipeline yang berkorelasi, yang mana sub-pipeline perlu mereferensikan nilai dari cakupan dokumen induk.
Contoh
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();
Perilaku
Variabel versus Kolom
Meskipun kolom merepresentasikan data yang disimpan dalam dokumen, variabel adalah nilai sementara yang hanya ada selama eksekusi pipeline.
| Kolom | Variabel | |
|---|---|---|
| Tujuan | mengakses atau menyimpan kolom ke dalam dokumen | membuat atau mengakses nilai sementara selama eksekusi pipeline |
| Penggunaan SDK | field("name") |
variable("name") |
| Cakupan | lokal ke dokumen saat ini | global ke pipeline dan sub-pipeline |
| Referensi Tidak Ditentukan | mengevaluasi ke absent |
menghasilkan error runtime |
Cakupan:
Meskipun kolom dicakup ke dokumen lokal, variabel ditentukan dalam cakupan
terpisah dan tetap dapat diakses di seluruh tahap hingga kemunculan pertama
tahap yang "menggabungkan" beberapa dokumen (seperti
aggregate(...) atau
distinct(...)). Tahap yang "menggabungkan" beberapa
dokumen tidak mengizinkan referensi variabel digunakan setelahnya karena dengan menggabungkan
hasil tahap sebelumnya, tidak ada lagi satu nilai untuk
variabel.
Lakukan: Merujuk variabel setelah memfilter kolom dokumen.
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();
Jangan: Merujuk variabel setelah agregasi.
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();
Referensi yang Tidak Ditentukan:
Meskipun mereferensikan kolom yang tidak ditentukan tidak masalah (dan hanya dievaluasi ke absent),
mencoba mereferensikan variabel yang tidak ditentukan akan gagal selama validasi
permintaan. Dalam hal ini, referensi kolom dapat dilihat sebagai melakukan pencarian
di peta saat runtime, sedangkan referensi variabel lebih mirip dengan variabel dalam
bahasa pemrograman yang dikompilasi secara statis.
Cakupan Global dan Subkueri
Variabel sangat penting saat bekerja dengan pipeline bertingkat. Sub-pipeline
dieksekusi dalam cakupannya sendiri dan hanya dapat mengakses kolom dokumen yang sedang diproses. Untuk menggunakan nilai dari dokumen "induk" di dalam
subkueri, Anda harus terlebih dahulu menentukannya sebagai variabel menggunakan tahap 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();
Variabel yang Tumpang-Tindih
Menentukan variabel dengan nama yang sudah ditentukan di tahap
let(...) sebelumnya akan menimpa variabel sebelumnya. Hal ini dapat digunakan untuk
memperbarui status sementara saat pipeline berlangsung.
Variabel yang dirujuk dalam sub-pipeline mengikuti aturan cakupan leksikal seperti yang ditemukan dalam banyak bahasa pemrograman dan mengacu pada variabel dengan nama yang sama yang ditentukan oleh pipeline terdekat (induk).
Perbandingan dengan add_fields(...)
Tahap let(...) berperilaku serupa dengan tahap
add_fields(...), tetapi alih-alih menambahkan
kolom ke dokumen, tahap ini menetapkan nilai ke variabel.