【问题标题】:MongoDB Aggregate $lookup on array of object with additional fieldMongoDB在具有附加字段的对象数组上聚合$lookup
【发布时间】:2020-08-14 06:48:40
【问题描述】:

我有两个不同的集合(下面的示例)methods & items。至于现在,我正在使用 3.6 之前的香草聚合查询 $lookup

MongoPlayground Example

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

问题是,如果我使用它,我会在原始集合的$lookup 阶段错过quantity 字段(来自methods.reagents 嵌入)。现在,我在lookup 之后立即返回quantity,但据我所知,Mongo 从 3.6 开始为lookup 查询引入了新语法,所以问题是:

它能否解决我收到以下结果的问题:

  {
    "_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
      }
    ]
  }

方法

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

项目

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

【问题讨论】:

    标签: javascript mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    使用$map$arrayElemAt 为每个reagent_items 查找对应的reagent 并应用$mergeObjects 以获取一个对象:

    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

    【讨论】:

    • 好吧,我几乎遇到了一个相关查询的问题:如果我在集合中的 _id 字段上有索引应该是 lookuped 并且 reagents 数组有 item_id 反转顺序,例如不是[1,2,3] but [3,2,1], well quantity`字段可能会在$map阶段之后丢失正确的item id。
    • @AlexZeDim 不确定我是否理解您的担忧,有一个{ $eq: [ "$$this._id", "$$ri._id" ] } 条件,因此订单不会影响匹配
    • 是的,我一开始没见过,至于现在,我正在重新检查这个东西。至于我的问题,很难用评论中的 500 个符号来描述,但由于模式模式错误,我毁了我的第一个数据库。
    • 你能回答这个问题吗? stackoverflow.com/questions/64661069/…@mickl
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 2020-04-23
    • 2018-08-06
    相关资源
    最近更新 更多