当另一个集合中存在数组中的项目时,如何在两个集合之间进行查找?

时间:2018-07-28 19:43:51

标签: mongodb mongodb-query aggregation-framework

在具有管道的查找中,我想从父文档的数组中获取链接记录。

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是一个数组,它也不接受。

我的整个方法正确吗?如何使这种魔术般的加入?

3 个答案:

答案 0 :(得分:2)

您朝着正确的方向前进,这里唯一想念的就是将exprin聚合运算符配合使用,该运算符与文档的相同字段相匹配

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整理数组并进行查找。