如何筛选Mongodb $ lookup结果以仅获取匹配的嵌套对象?

时间:2019-12-05 11:58:46

标签: mongodb mongodb-query aggregation-framework

我有一个customers集合,例如;

{ 
  "_id" : ObjectId("5de8c07dc035532b489b2e23"),
  "name" : "sam",
  "orders" : [{"ordername" : "cola"},{"ordername" : "cheesecake"}]
}

还有waiters集合,例如;

{   
    "_id" : ObjectId("5de8bc24c035532b489b2e20"),
    "waiter" : "jack",
    "products" : [{"name" : "cola", "price" : "4"}, 
                  {"name" : "water", "price" : "2"}, 
                  {"name" : "coffee", "price" : "8" }]
}
{   
    "_id" : ObjectId("5de8bdc7c035532b489b2e21"),
    "waiter" : "susan",
    "products" : [{"name" : "cheesecake", "price" : "12" }, 
                  {"name" : "apple pie", "price" : "14" }]
}

我想通过匹配“ products.name”和“ orders.ordername”将waiters集合中的对象加入customers集合中。但是,结果包括waiters集合中的整个文档,但是,我只想要文档中匹配的对象。这就是我想要的;

ordered:[ 
  {"name" : "cola", "price" : "4"},
  {"name" : "cheesecake", "price" : "12" },
]

我尝试了$lookup有无管道,并进行了过滤,但无法获得此结果。预先感谢。

1 个答案:

答案 0 :(得分:1)

您有一个正确的想法,由于结构类似,我们只需要稍微“整理”数据即可。

db.collection.aggregate([
    {
        $addFields: {
            "orderNames":
                {
                    $reduce: {
                        input: "$orders",
                        initialValue: [],
                        in: {$concatArrays: [["$$this.ordername"], "$$value"]}
                    }
                }
        }
    },
    {
      $lookup:
          {
            from: "waiters",
            let: {orders: "$orderNames"},
            pipeline: [
                {
                    $unwind: "$products"
                },
                {
                    $match:
                        {
                            $expr:{$in: ["$products.name", "$$orders"]},
                        }
                },
                {
                    $group: {
                        _id: "$products.name",
                        price: {$first: "$products.price"}
                    }
                },
                {
                    $project: {
                        _id: 0,
                        price: 1,
                        name: "$_id"
                    }
                }
            ],
            as: "ordered"
        }
    }
])
  • 感觉就像您可以从映射项目到价格的新集合中受益。可以节省大量时间。