我遵循了下面的SO线程,但仍然无法正常工作。
MongoDB Join on multiple fields [duplicate]
Multiple join conditions using the $lookup operator
我的collection1
如下:
{
_id: 5bc2e44a106342152cd83e97,
description:
{
status: 'Good',
machine: 'X',
},
order: 'A',
lot: '1'
}
我的collection2
如下:
{
_id: 5bc2e44a106342152cd83e80,
isCompleted: false,
serialNo: '1',
batchNo: '2',
product: [{
order: 'A', lot: '1',
order: 'A', lot: '2'
}]
}
我期望的结果如下:
{
_id: 5bc2e44a106342152cd83e97,
description:
{
status: 'Good',
machine: 'X',
},
order: 'A',
lot: '1' ,
isCompleted: false,
serialNo: '1',
batchNo: '2'
}
聚合操作必须基于以下条件:product
中的collection2
数组包含order
和lot
与order
相同和lot
中的collection1
。
以下是我尝试的2个代码,但均无济于事。请给我一些指导。
db.collection2.aggregate([
{ $unwind : "$product" }
{
$lookup: {
from: "collection1",
localField: "product.order",
foreignField: "order",
as: "results"
}
},
{
$replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$results", 0 ] }, "$$ROOT" ] } }
}]
然后,我尝试了基于文档的多重联接条件,但是没有运气
db.collection2.aggregate([
{ $unwind : "$product" },
{ $lookup: {
from: "collection1",
let: { order: "$order", lot: "$lot" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: [ "$product.order", "$$order" ] },
{ $eq: [ "$product.lot", "$$lot"] }
]
}
}
}
],
as: "results"
}
},
{
$replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$results", 0 ] }, "$$ROOT" ] } }
}]
任何提示,指导或解决方案将不胜感激!谢谢!
答案 0 :(得分:0)
您快到了,只是与查找中引用字段的一小部分混合在一起:
{
from: "collection1",
let: { order: "$product.order", lot: "$product.lot" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: [ "$order", "$$order" ] },
{ $eq: [ "$lot", "$$lot"] }
]
}
}
}],
as: "results"
}
这将适用于u:)
答案 1 :(得分:0)
假设您的文档结构如下:
{
_id: 5bc2e44a106342152cd83e80,
isCompleted: false,
serialNo: '1',
batchNo: '2',
product: [ // note the subdocuments here
{ order: 'A', lot: '1' },
{ order: 'A', lot: '2' }
]
}
您可以运行此命令以获得所需的结果:
db.collection1.aggregate([{
$lookup: {
from: "collection2",
let: { order: "$order", lot: "$lot" },
pipeline: [{
$match: {
$expr: { $in: [ { order: "$$order", lot: "$$lot" }, "$product"] }
}
}],
as: "isCompleted" // we're just using the "isCompleted" field in order to avoid having to remove some "results" (or something) field later
}
}, {
$addFields: {
"isCompleted": { $arrayElemAt: [ "$isCompleted", 0 ] } // take the first matched document only
}
}, {
$addFields: { // add the required fields to the top level structure
"isCompleted": "$isCompleted.isCompleted", // here, we set the "isCompleted" field to its real value
"serialNo": "$isCompleted.serialNo",
"batchNo": "$isCompleted.batchNo"
}
}])