【问题标题】:mongoose populate array with aggregate and keep format猫鼬用聚合填充数组并保持格式
【发布时间】:2022-01-21 16:26:44
【问题描述】:

我有以下模型,它有一个类别数组,由具有类别的对象组成:ObjectId 和选项:[ObjectId, ObjectId]。

const page = new Schema({
   "categories":[
      {
         "category":{
            "type":"Schema.Types.ObjectId",
            "ref":"Category",
            "_id":false,
            "index":true
         },
         "options":[
            {
               "type":"Schema.Types.ObjectId",
               "ref":"CategoryOptions",
               "_id":false,
               "index":true
            }
         ],
         "_id":false
      }
   ]
})

我正在尝试使用 .aggregate 方法填充字段。但是,不知何故,我无法在不丢失整体结构的情况下让它工作。 我的输出最终应该是这样的:

[
   {
      "category":{
         "_id":"ObjectId",
         "name":"name of category"
      },
      "options":[
         {
            "_id":"ObjectId",
            "name":"name of options"
         },
         {
            "_id":"ObjectId",
            "name":"name of options"
         }
      ]
   }
]

我当前的聚合如下所示:

{
    $lookup: {
      from: 'categories',
      localField: 'categories.category',
      foreignField: '_id',
      as: 'categories',
      pipeline: [
        {
          $lookup: {
            from: 'categoryoptions',
            localField: 'options',
            foreignField: '_id',
            as: 'options'
          }
        }
      ]
    }
  }

但这不起作用,因为它只填充类别并将结构展平为类别:[...results]

知道如何在不丢失给定结构的情况下简单地填充值吗?

更新的解决方案:

{
        $unwind: {
          path: '$categories'
        }
      }, {
        $lookup: {
          from: 'categories',
          localField: 'categories.category',
          foreignField: '_id',
          as: 'categoryObjects.category'
        }
      }, {
        $set: {
          categoryObjects: {
            category: {
              $first: '$categoryObjects.category'
            }
          }
        }
      }, {
        $lookup: {
          from: 'categoryoptions',
          localField: 'categories.options',
          foreignField: '_id',
          let: {
            cid: '$categories.options'
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $in: [
                    '$_id', '$$cid'
                  ]
                }
              }
            }
          ],
          as: 'categoryObjects.options'
        }
      }, {
        $group: {
          _id: '$_id',
          categories: {
            $push: '$categoryObjects'
          },
         __v: {
            $first: '$__v'
          }
        }
      }
enter code here

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    据我所知并且目前已经研究过,您不能在另一个$lookup 中使用$lookup。 mongodb 查询的其余部分的问题会覆盖数据库中存在的现有categories 字段,而$lookup 结果由于名称相同而像as: 'categories', 一样编写。带有 ObjectIds 的原始 options 数组也被覆盖。您必须将聚合分解为 2 个 $lookup,然后使用 $project 聚合来获得所需的结构,如下所示:

    [
      {
        '$lookup': {
          'from': 'categories',
          'localField': 'categories.category',
          'foreignField': '_id',
          'as': 'categories_temp'
        }
      }, {
        '$lookup': {
          'from': 'options',
          'localField': 'categories.options',
          'foreignField': '_id',
          'as': 'options_temp'
        }
      }, {
        '$project': {
          'categories.category': '$categories_temp',
          'categories.options': '$options_temp'
        }
      }
    ]
    

    【讨论】:

    • 我刚刚测试过了。但是它不像你建议的那样工作。我已经想出了一个解决方案并更新了我的问题。请看一下。
    猜你喜欢
    • 2019-08-29
    • 2017-01-23
    • 2015-12-23
    • 2016-12-19
    • 2014-04-19
    • 1970-01-01
    • 2015-07-13
    • 2015-04-01
    • 2016-06-10
    相关资源
    最近更新 更多