使用MongoDB 4.2和MongoDB Atlas来测试聚合管道。
我有这个products集合,其中包含具有以下架构的文档:
{
"name": "TestProduct",
"relatedList": [
ObjectId("someId"),
ObjectId("anotherId")
]
}
然后有这个cities集合,其中包含具有此架构的文档:
{
"name": "TestCity",
"instructionList": [
{ related_id: ObjectId("anotherId"), foo: bar},
{ related_id: ObjectId("someId"), foo: bar}
{ related_id: ObjectId("notUsefulId"), foo: bar}
...
]
}
我的目标是将两个集合都连接起来以输出类似的内容(该操作是从城市文档的指令列表中选择每个相关对象,然后将其放入产品文档的相关列表中:
]{
"name": "TestProduct",
"relatedList": [
{ related_id: ObjectId("someId"), foo: bar},
{ related_id: ObjectId("anotherId"), foo: bar},
]
}
我尝试使用$查找操作者的聚集等this:
$lookup:{
from: 'cities',
let: {rId:'$relatedList._id'},
pipeline: [
{
$match: {
$expr: {
$eq: ["$instructionList.related_id", "$$rId"]
}
}
},
]
}
但是它不起作用,这种复杂的管道语法让我有些迷茫。
我相信您只需要$ unwind数组以查找该关系,然后$ group重新收集它们。也许像这样:
.aggregeate([
{$unwind:"relatedList"},
{$lookup:{
from:"cities",
let:{rId:"$relatedList.id"}
pipeline:[
{$match:{$expr:{$eq:["$instructionList.related_id", "$$rId"]}}},
{$unwind:"$instructionList"},
{$match:{$expr:{$eq:["$instructionList.related_id", "$$rId"]}}},
{$project:{_id:0, instruction:"$instructionList"}}
],
as: "lookedup"
}},
{$addFields: {"relatedList.foo":"$lookedup.0.instruction.foo"}},
{$group: {
_id:"$_id",
root: {$first:"$$ROOT"},
relatedList:{$push:"$relatedList"}
}},
{$addFields:{"root.relatedList":"$relatedList"}},
{$replaceRoot:{newRoot:"$root"}}
])
关于每个阶段的一点:
foo
字段分配给从relatedList
中的对象root
,它现在应该是原始文档,并将匹配的foo
添加到每个relatedList
元素中