首页 > 解决方案 > 如何过滤 Mongodb $lookup 结果以仅获取匹配的嵌套对象?

问题描述

我有一个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了有无管道和过滤器,但无法得到这个结果。提前致谢。

标签: mongodbmongodb-queryaggregation-framework

解决方案


你的想法是对的,我们只需要“按摩”一下数据,因为它的结构如下:

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"
        }
    }
])
  • 感觉就像您可以从一组新的将项目映射到价格中受益。可能会为您节省大量时间。

推荐阅读