【问题标题】:MongoDB: Populate reference in $group when aggregating?MongoDB:聚合时填充 $group 中的引用?
【发布时间】:2021-04-21 17:26:05
【问题描述】:

我有一个需要按年份分组的集合。我的聚合管道是这样的:

const WorkHistoryByYear = await this.workHistroyModel.aggregate([
  {
    $group: {
      _id: '$year',
      history: {
        $push: '$$ROOT'
      }
    }
  }
]);

按预期工作,返回:

[{
  "_id": 2003,
  "history": [
    {
      "_id": "600331b3d84ac418877a0e5a",
      "tasksPerformed": [
        "5fffb180a477c4f78ad67331",
        "5fffb18aa477c4f78ad67332"
      ],
      "year": 2003
    },
    {
      "_id": "600331dcd84ac418877a0e5c",
      "tasksPerformed": [
        "5fffb180a477c4f78ad67331"
      ],
      "year": 2003
    }
  ]
}]

但如果可能,我想填充一个字段。

WorkHistory 架构有一个字段 tasksPerformed,它是 ObjectId 引用的数组。这是Task 架构:

export const TaskSchema = new Schema({
  active: {
    type: Schema.Types.Boolean,
    default: true,
  },
  title: {
    type: Schema.Types.String,
    required: true,
  },
  order: {
    type: Schema.Types.Number,
    index: true,
  }
});

是否可以在聚合中填充引用的模型? $lookup 似乎是我所需要的,但在遵循文档时我还没有让它工作。

我没有做很多数据库工作,所以我很难找到合适的运算符来使用,我也看到过类似的问题,但没有明确的答案。

编辑:

从@varman 的回答中添加代码后,我现在的回报是:

{
  "_id": 2003,
  "history": {
    "_id": "600331b3d84ac418877a0e5a",
    "tasksPerformed": [
      "5fffb180a477c4f78ad67331",
      "5fffb18aa477c4f78ad67332"
    ],
    "year": 2003,
    "history": {
      "tasksPerformed": []
    }
  }
}

为了帮助匹配,我将 ObjectId 引用转换为字符串,但我仍然做得不够。

【问题讨论】:

  • 你能发布一些示例数据吗
  • @varman 我添加了聚合数据的精简示例
  • 模型内的人口是可能的,你所说的$lookup也是正确的。我们还有其他你需要加入的收藏吗?
  • @varman 我已经为相关的“任务”模型添加了架构
  • TaskSchema 有工作历史的参考吗?

标签: mongodb mongoose


【解决方案1】:

您可以进行查找以加入两个集合

  • $unwind 解构数组。 (数组到对象)
  • $lookup加入收藏
  • $group再次重构解构数组

上述结果的脚本是

db.workHistory.aggregate([
  {
    "$unwind": "$history"
  },
  {
    "$lookup": {
      "from": "taskSchema",
      "localField": "history.tasksPerformed",
      "foreignField": "_id",
      "as": "history.tasksPerformed"
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "history": {
        "$push": "$history"
      }
    }
  }
])

工作Mongo playground

但是在分组之前,你的集合看起来像这样

db={
  "workHistory": [
    {
      "_id": 2003,
      "history": [
        {
          "_id": "600331b3d84ac418877a0e5a",
          "tasksPerformed": [
            "5fffb180a477c4f78ad67331",
            "5fffb18aa477c4f78ad67332"
          ],
          "year": 2003
        },
        {
          "_id": "600331dcd84ac418877a0e5c",
          "tasksPerformed": [
            "5fffb180a477c4f78ad67331"
          ],
          "year": 2003
        }
      ]
    }
  ],
  "taskSchema": [
    {
      "_id": "5fffb180a477c4f78ad67331",
      "active": true,
      "title": "first"
    },
    {
      "_id": "5fffb18aa477c4f78ad67332",
      "active": true,
      "title": "second"
    }
  ]
}

由于$unwind 很昂贵,我们可以进行聚合

db.workHistory.aggregate([
  {
    "$lookup": {
      "from": "taskSchema",
      "localField": "tasksPerformed",
      "foreignField": "_id",
      "as": "tasksPerformed"
    }
  },
  {
    $group: {
      _id: "$year",
      history: {
        $push: "$$ROOT"
      }
    }
  }
])

工作Mongo playground

【讨论】:

  • 嗯。我不确定我的收藏有什么问题,但我的汇总正在返回:{ "_id": 2003, "history": { "_id": "600331b3d84ac418877a0e5a", "tasksPerformed": [ "5fffb180a477c4f78ad67331", "5fffb18aa477c4f78ad67332" ], "year": 2003, "history": { "tasksPerformed": [] } } }
  • 我将 ObjectID 引用转换为字符串,但这也没有帮助。
  • 我已经更新了答案,第二个答案对你有帮助吗?如果不是,你能给我一个这样的 mongoplayground 来显示你的两个集合的样本数据吗?
  • “taskSchema”存储为“tasks”集合。我更新了 Mongo 操场示例以匹配该名称,它在那里工作,它只是在我的 NestJS 代码中不起作用
  • 我没有看到您更改了localFieldas 属性以删除history.。我删除了这些,它按预期工作。
【解决方案2】:

你也可以这样做without an unwind:

db.WorkHistory.aggregate(
[
    {
        $lookup: {
            from: "Tasks",
            localField: "tasksPerformed",
            foreignField: "_id",
            as: "tasksPerformed"
        }
    },
    {
        $group: {
            _id: "$year",
            history: { $push: "$$ROOT" }
        }
    }
])

【讨论】:

    猜你喜欢
    • 2021-10-22
    • 1970-01-01
    • 2021-03-19
    • 2020-04-18
    • 2021-02-16
    • 2016-04-29
    • 2021-06-11
    • 2019-10-25
    • 1970-01-01
    相关资源
    最近更新 更多