简体   繁体   English

MongoDB 使用附加字段对 object 数组进行聚合 $lookup

[英]MongoDB Aggregate $lookup on array of object with additional field

I have two different collections (example below) methods & items .我有两种不同的 collections(下面的示例)方法项目 As for now, I'm using pre 3.6 vanilla aggregation query for $lookup :至于现在,我正在使用 3.6 之前的香草聚合查询$lookup

MongoPlayground Example MongoPlayground 示例

  {
    $lookup: {
      from: "items",
      localField: "reagents._id",
      foreignField: "_id",
      as: "reagent_items"
    }
  }

The problem is that if I am using it, I miss quantity field (from methods.reagents embedded) during $lookup stage from original collection.问题是,如果我使用它,我会在原始集合的$lookup阶段错过quantity字段(来自嵌入的methods.reagents )。 For now, I return quantity right after lookup but as I heard, Mongo introduced from 3.6 a new syntax for lookup queries, so the question is:目前,我在lookup后立即返回quantity ,但正如我听说的那样,Mongo 从 3.6 引入了一种用于lookup查询的新语法,所以问题是:

Can it solve my problem for receiving the following results:它能否解决我收到以下结果的问题:

  {
    "_id": 1,
    "name": "Test",
    "reagent_items": [ // <= the exact schema of what I need after lookup
      {
        "_id": 1,
        "name": "ItemOne",
        "other": "field",
        "quantity": 2 //quantity field from original {array of objects} after lookup
      },
      {
        "_id": 2,
        "name": "ItemTwo",
        "other": "field",
        "quantity": 4 //quantity field from original {array of objects} after lookup
      }
    ],
    "reagents": [ //original reagents field here just for example, we could remove it
      {
        "_id": 1,
        "quantity": 2
      },
      {
        "_id": 2,
        "quantity": 4
      }
    ]
  }

methods方法

    {
      "_id": 1,
      "name": "Test",
      "reagents": [
        {
          _id: 1,
          quantity: 2
        },
        {
          _id: 2,
          quantity: 4
        }
      ]
    }

items项目

    {
      "_id": 1,
      "name": "ItemOne",
      "other": "field"
    },
    {
      "_id": 2,
      "name": "ItemTwo",
      "other": "field"
    }

Use $map along with $arrayElemAt to find corresponding reagent for each reagent_items and the apply $mergeObjects to get one object:使用$map$arrayElemAt为每个reagent_items找到对应的reagent ,并应用$mergeObjects获得一个 object:

db.methods.aggregate([
    {
        $lookup: {
            from: "items",
            localField: "reagents._id",
            foreignField: "_id",
            as: "reagent_items"
        }
    },
    {
        $project: {
            _id:1,
            name: 1,
            reagents: 1,
            reagent_items: {
                $map: {
                    input: "$reagent_items",
                    as: "ri",
                    in: {
                        $mergeObjects: [
                            "$$ri",
                            {
                                $arrayElemAt: [ { $filter: { input: "$reagents", cond: { $eq: [ "$$this._id", "$$ri._id" ] } } }, 0 ]
                            }
                        ]
                    }
                }
            }
        }
    }
])

Mongo Playground蒙戈游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM