Chúng ta có thể thực hiện nhiều điều kiện tham gia với $lookup
nhà điều hành đường ống tổng hợp trong phiên bản 3.6 và mới hơn.
Chúng ta cần gán giá trị của các trường cho biến bằng cách sử dụng let
trường tùy chọn; sau đó bạn truy cập các biến đó trong pipeline
các giai đoạn trường mà bạn chỉ định đường dẫn để chạy trên các bộ sưu tập.
Lưu ý rằng trong $match
giai đoạn này, chúng tôi sử dụng $expr
toán tử truy vấn đánh giá để so sánh giá trị của các trường.
Giai đoạn cuối cùng trong quy trình là $replaceRoot
giai đoạn đường ống tổng hợp nơi chúng tôi chỉ cần hợp nhất $lookup
kết quả với một phần của $$ROOT
tài liệu sử dụng $mergeObjects
nhà điều hành.
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"
}
]
}
}
}
]
)
Đường ống này tạo ra một cái gì đó giống như sau:
{
"_id" : ObjectId("59e1ad7d36f42d8960c06022"),
"user1" : 1,
"user2" : 2,
"percent" : 0.3,
"percent1" : 0.56
}
Nếu bạn không sử dụng phiên bản 3.6+, trước tiên bạn có thể tham gia bằng cách sử dụng một trong các trường của mình, giả sử là "user1", sau đó từ đó bạn giải phóng mảng của tài liệu phù hợp bằng cách sử dụng $unwind
nhà điều hành đường ống tổng hợp. Giai đoạn tiếp theo trong quy trình là $redact
giai đoạn mà bạn lọc ra những tài liệu có giá trị của "user2" từ tập hợp "đã kết hợp" và tài liệu đầu vào không bằng nhau bằng cách sử dụng $$KEEP
và $$PRUNE
biến hệ thống. Sau đó, bạn có thể định hình lại tài liệu của mình trong $project
sân khấu.
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"
}}
])
nơi sản xuất:
{
"_id" : ObjectId("572daa87cc52a841bb292beb"),
"user1" : 1,
"user2" : 2,
"percent1" : 0.56,
"percent2" : 0.3
}
Nếu các tài liệu trong bộ sưu tập của bạn có cấu trúc giống nhau và bạn thấy mình thực hiện thao tác này thường xuyên, thì bạn nên cân nhắc để hợp nhất hai bộ sưu tập thành một hoặc chèn tài liệu trong các bộ sưu tập đó vào một bộ sưu tập mới.
db.collection3.insertMany(
db.collection1.find({}, {"_id": 0})
.toArray()
.concat(db.collection2.find({}, {"_id": 0}).toArray())
)
Sau đó, $group
tài liệu của bạn bởi "user1" và "user2"
db.collection3.aggregate([
{ "$group": {
"_id": { "user1": "$user1", "user2": "$user2" },
"percent": { "$push": "$percent" }
}}
])
mang lại:
{ "_id" : { "user1" : 1, "user2" : 2 }, "percent" : [ 0.56, 0.3 ] }