Mongodb 查找具有组合结果的元素数组

Mongodb lookup array of elements with combined result

这是我的两份文件

订单文件:

{
   "_id":"02a33b9a-284c-4869-885e-d46981fdd679",
   "context":{
      "products":[
         {
         "id": "e68fc86a-b4ad-4588-b182-ae9ee3db25e4",
         "version": "2020-03-14T13:18:41.296+00:00"
         }
      ],
   },
}

产品文档:

{
   "_id":"e68fc86a-b4ad-4588-b182-ae9ee3db25e4",
   "context":{
      "name": "My Product",
      "image": "someimage"
   },
}

所以我正在尝试查找订单文档中的产品,但结果应包含组合字段,如下所示:

"products":[
             {
             "_id": "e68fc86a-b4ad-4588-b182-ae9ee3db25e4",
             "version": "2020-03-14T13:18:41.296+00:00",
             "name": "My Product",
             "image": "someimage"
             }
          ],

不确定该怎么做,我应该在查找之外还是在内部进行?这是我的汇总

Orders.aggregate([
{
   "$lookup":{
      "from":"products",
      "let":{
         "products":"$context.products"
      },
      "pipeline":[
         {
            "$match":{
               "$expr":{
                  "$in":[
                     "$_id",
                     "$$products.id"
                  ]
               }
            }
         },
         {
            "$project":{
               "_id":0,
               "id":1,
               "name":"$context.name"
            }
         }
      ],
      "as":"mergedProducts"
   }
},
{
   "$project":{
      "context":"$context",
      "mergedProducts":"$mergedProducts"
   }
},
]);

您需要 运行 通过 运行 宁 $map along with $arrayElemAt to get single pair from both arrays and then apply $mergeObjects$lookup 之外的映射以获得一个对象作为结果:

db.Order.aggregate([
    {
        $lookup: {
            from: "products",
            localField: "context.products.id",
            foreignField: "_id",
            as: "productDetails"
        }
    },
    {
        $addFields: {
            productDetails: {
                $map: {
                    input: "$productDetails",
                    in: {
                        _id: "$$this._id",
                        name: "$$this.context.name"
                    }
                }
            }
        }
    },
    {
        $project: {
            _id: 1,
            "context.products": {
                $map: {
                    input: "$context.products",
                    as: "prod",
                    in: {
                        $mergeObjects: [
                            "$$prod",
                            { $arrayElemAt: [ { $filter: { input: "$productDetails", cond: { $eq: [ "$$this._id", "$$prod.id" ] } } }, 0 ] }
                        ]
                    }
                }
            }
        }
    }
])

Mongo Playground

最后一步的目标是获取两个数组:productsproductDetails$lookup 的输出)并找到它们之间的匹配项。我们知道总有一个匹配项,所以我们只能得到一个项目 $arrayElemAt 0。作为 $map 的输出,将有一个包含 "merged" 个文档的数组。