在具有管道的查找中,我想从父文档的数组中获取链接记录。
calculate()
当// Orders
[{
"_id" : ObjectId("5b5b91a25c68de2538620689"),
"Name" : "Test",
"Products" : [
ObjectId("5b5b919a5c68de2538620688"),
ObjectId("5b5b925a5c68de2538621a15")
]
}]
// Products
[
{
"_id": ObjectId("5b5b919a5c68de2538620688"),
"ProductName": "P1"
},
{
"_id": ObjectId("5b5b925a5c68de2538621a15"),
"ProductName": "P2"
}
,
{
"_id": ObjectId("5b5b925a5c68de2538621a55"),
"ProductName": "P3"
}
]
字段为数组时,如何在订单和产品之间进行查询!
我尝试了此查询
Products
这不起作用,因为db.getCollection("Orders").
aggregate(
[
{
$lookup:
{
from: "Products",
let: { localId: "$_id" , prods: "$Products" },
pipeline: [
{
"$match":
{
"_id" : { $in: "$$prods" }
}
},
{
$project:
{
"_id": "$_id",
"name": "$prods" ,
}
}
],
as: "linkedData"
}
},
{
"$skip": 0
},
{
"$limit": 1
},
]
)
需要一个数组,即使$in
是一个数组,它也不接受。
我的整个方法正确吗?如何使这种魔术般的加入?
答案 0 :(得分:2)
您朝着正确的方向前进,这里唯一想念的就是将expr
与in
聚合运算符配合使用,该运算符与文档的相同字段相匹配
db.getCollection("Orders").aggregate([
{ "$lookup": {
"from": "Products",
"let": { "localId": "$_id" , "prods": "$Products" },
"pipeline": [
{ "$match": { "$expr": { "$in": [ "$_id", "$$prods" ] } } },
{ "$project": { "_id": 1, "name": "$ProductName" } }
],
"as": "linkedData"
}},
{ "$skip": 0 },
{ "$limit": 1 }
])
请参阅文档here
答案 1 :(得分:1)
您只需要常规的$lookup,该文档指出:
如果您的localField是一个数组,则可能要在管道中添加$ unwind阶段。否则,localField和foreignField之间的相等条件为foreignField:{$ in:[localField.elem1,localField.elem2,...]}。
因此对于以下聚合:
db.Orders.aggregate([
{
$lookup: {
from :"Products",
localField: "Products",
foreignField: "_id",
as: "Products"
}
}
])
您将获得以下示例数据结果:
{
"_id" : ObjectId("5b5b91a25c68de2538620689"),
"Name" : "Test",
"Products" : [
{
"_id" : ObjectId("5b5b919a5c68de2538620688"),
"ProductName" : "P1"
},
{
"_id" : ObjectId("5b5b925a5c68de2538621a15"),
"ProductName" : "P2"
}
]
}
答案 2 :(得分:0)
您是否尝试在查找之前放松。使用unwind整理数组并进行查找。