嵌套数组上的猫鼬聚合

时间:2021-01-09 04:39:47

标签: javascript mongodb mongoose aggregate

我有一个架构,它有一个子数组,它的每个元素都引用另一个架构,如下所示:

{
 _id: "5fed222d806311ec81d6df23"
 someOtherNestedDoc: {
    _id: "abc",
    someOtherField: 10
 },
 matches: [
   {
      _id: "5fed222d806311ec81d6daf3",
      user: "5fed222d806311ec81d6dcf3",
      probability: 10
   },
   {
      _id: "5fed222d806311ec81d6d1f3",
      user: "5fed222d806311ec81d62cf3",
      probability: 20
   },
 ]
}

我想做一个 Mongoose 聚合,在其中我查找每个匹配项的用户引用,并且只为它投影 3 个字段,2 个已经存在,第三个是该模式数组的总和,以便最后,我有这样的事情:

{
 _id: "5fed222d806311ec81d6df23"
 someOtherNestedDoc: {
    _id: "abc",
    someOtherField: 10
 },
 matches: [
   {
      _id: "5fed222d806311ec81d6daf3",
      user: {
         firstName: "Max",
         lastName: "Mustermann",
         totalExpenses: 100
      },
      probability: 10
   },
   {
      _id: "5fed222d806311ec81d6d1f3",
      user: {
         firstName: "Herbert",
         lastName: "Mustermann",
         totalExpenses: 200
      },,
      probability: 20
   },
 ]
}

用户看起来像这样:

{
  _id: "5fed222d806311ec81d6dcf3",
  firstName: "Max",
  lastName: "Mustermann",
  password: "test",
  expenses: [
    {
      _id: 1,
     price: 50
    },
    {
      _id: 2,
     price: 50
    },
   ]
}

{
  _id: "5fed222d806311ec81d62cf3",
  firstName: "Herbert",
  lastName: "Mustermann",
  password: "test2",
  expenses: [ 
    {
      _id: 3,
     price: 75
    },
    {
      _id: 4,
     price: 125
    },
   ]
}

1 个答案:

答案 0 :(得分:1)

  • $unwind 解构 matches 数组
  • $lookup 带有用户集合并在 let 中传递用户 ID,
    • $match userId 条件
    • $project 显示必填字段,获取 expenses.price 的总和
  • $unwind 解构 user 数组
  • $group by _id 并重建 matches 数组
db.col1.aggregate([
  { $unwind: "$matches" },
  {
    "$lookup": {
      "from": "user",
      let: { userId: "$matches.user" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$userId"] } } },
        {
          $project: {
            _id: 0,
            firstName: 1,
            lastName: 1,
            totalExpenses: { $sum: "$expenses.price" }
          }
        }
      ],
      "as": "matches.user"
    }
  },
  { $unwind: "$matches.user" },
  {
    $group: {
      _id: "$_id",
      matches: { $push: "$matches" }
    }
  }
])

Playground