首页 > 解决方案 > mongodb嵌套数组元素$lookup

问题描述

我有两个系列,ordersproducts. 我喜欢加入所有order.items[]toproducts集合以向items[]

样本数据:
订单
[{ _id: 1, items: [ { product_id: 1, price: 1.99, qty: 2 }, { product_id: 2, price: 3.99, qty: 5 } ]}]
产品
[{ _id: 1, name: "Product 1" }, { _id: 2, name: "Product 2 }]

预期输出:
[{ _id: 1, items: [ { product_id: 1, name: "Product 1", price: 1.99, qty: 2 }, { product_id: 2, name: "Product 2",, price: 3.99, qty: 5 } ]}]

我尝试使用 $lookup 和管道(mongodb 3.6)并且没有获得名称值,甚至匹配都不起作用。

感谢您的帮助!

标签: mongodbaggregation-framework

解决方案


此查询将对您有所帮助,如果我没有使用 v3.6,请见谅。

db.orders.aggregate([
{
    $unwind: "$items"
},
{
     $lookup:
       {
         from: "products",
         localField: "items.product_id",
         foreignField: "_id",
         as: "tproduct"
       }
},
{ 
    $project: 
    {
        "_id" : 1,
        "items.product_id" : 1,
        "items.name" : { $arrayElemAt: ["$tproduct.name", 0] },
        "items.price" : 1,
        "items.qty" : 1
    }
},
{
    $group : 
    { 
        _id : "$_id", 
        items: { $push: "$items" } 
    }
}
])

它们是我将解释的 4 个阶段:

  1. $unwind 将为数组中的每个元素创建一个对象。
  2. $lookup 会找到正确的产品,记住 Product._id 应该是唯一的。
  3. $project 将格式化我的文档,并在 items.name 中获取查找语句的第一个元素。
  4. $group 将使用 _id 对每个项目进行分组并将其推送到一个新数组中。

我很确定有更清洁和更简单的方法来编写这个,但这应该没有问题。


推荐阅读