Kita bisa melakukan beberapa kondisi join dengan $lookup
operator pipeline agregasi di versi 3.6 dan yang lebih baru.
Kita perlu menetapkan nilai bidang ke variabel menggunakan let
bidang opsional; Anda kemudian mengakses variabel-variabel tersebut di pipeline
tahapan bidang tempat Anda menentukan saluran yang akan dijalankan pada koleksi.
Perhatikan bahwa di $match
tahap, kami menggunakan $expr
operator kueri evaluasi untuk membandingkan nilai bidang.
Tahap terakhir dalam pipeline adalah $replaceRoot
tahap pipa agregasi di mana kita cukup menggabungkan $lookup
hasil dengan bagian dari $$ROOT
dokumen menggunakan $mergeObjects
operator.
db.collection2.aggregate([
{
$lookup: {
from: "collection1",
let: {
firstUser: "$user1",
secondUser: "$user2"
},
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: [
"$user1",
"$$firstUser"
]
},
{
$eq: [
"$user2",
"$$secondUser"
]
}
]
}
}
}
],
as: "result"
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects:[
{
$arrayElemAt: [
"$result",
0
]
},
{
percent1: "$$ROOT.percent1"
}
]
}
}
}
]
)
Pipeline ini menghasilkan sesuatu yang terlihat seperti ini:
{
"_id" : ObjectId("59e1ad7d36f42d8960c06022"),
"user1" : 1,
"user2" : 2,
"percent" : 0.3,
"percent1" : 0.56
}
Jika Anda tidak menggunakan versi 3.6+, pertama-tama Anda dapat bergabung menggunakan salah satu bidang Anda, katakanlah "user1" kemudian dari sana Anda melepas larik dokumen yang cocok menggunakan $unwind
operator pipa agregasi. Tahap berikutnya dalam pipeline adalah $redact
tahap di mana Anda memfilter dokumen-dokumen di mana nilai "user2" dari koleksi "bergabung" dan dokumen input tidak sama menggunakan $$KEEP
dan $$PRUNE
variabel sistem. Anda kemudian dapat membentuk kembali dokumen Anda di $project
panggung.
db.collection1.aggregate([
{ "$lookup": {
"from": "collection2",
"localField": "user1",
"foreignField": "user1",
"as": "collection2_doc"
}},
{ "$unwind": "$collection2_doc" },
{ "$redact": {
"$cond": [
{ "$eq": [ "$user2", "$collection2_doc.user2" ] },
"$$KEEP",
"$$PRUNE"
]
}},
{ "$project": {
"user1": 1,
"user2": 1,
"percent1": "$percent",
"percent2": "$collection2_doc.percent"
}}
])
yang menghasilkan:
{
"_id" : ObjectId("572daa87cc52a841bb292beb"),
"user1" : 1,
"user2" : 2,
"percent1" : 0.56,
"percent2" : 0.3
}
Jika dokumen dalam koleksi Anda memiliki struktur yang sama dan Anda sering melakukan operasi ini, maka Anda harus mempertimbangkan untuk menggabungkan dua koleksi menjadi satu atau menyisipkan dokumen dalam koleksi tersebut ke dalam koleksi baru.
db.collection3.insertMany(
db.collection1.find({}, {"_id": 0})
.toArray()
.concat(db.collection2.find({}, {"_id": 0}).toArray())
)
Kemudian $group
dokumen Anda dengan "user1" dan "user2"
db.collection3.aggregate([
{ "$group": {
"_id": { "user1": "$user1", "user2": "$user2" },
"percent": { "$push": "$percent" }
}}
])
yang menghasilkan:
{ "_id" : { "user1" : 1, "user2" : 2 }, "percent" : [ 0.56, 0.3 ] }