【问题标题】:how to use mongoose aggregation to get sum of two matching documents depending on field如何使用猫鼬聚合根据字段获取两个匹配文档的总和
【发布时间】:2021-03-01 06:24:16
【问题描述】:

我有两个集合“Employee”、“Office”

我试图找出每个包含办公室代码的区域中有多少员工。但同一地区可能有不止一个办公室。

这就是我的 Office 文档的样子

[
  {
    _id: "5b7d0f77e231b6b530b0ee5a",
    code: "OB123456",
    city: "Canmore"
    // some other fields            
  },
  {
    _id: "5b7d0f77e531b6b530b0ee5b",
    code: "OB858758",
    city: "Vancouver"
  },
  {
    _id: "5b7d0f77e531b6b530b0ee5d",
    code: "EE858758",
    city: "Vancouver"
  },
]

这就是我的员工文档的样子

[
  {
    _id: "5b7d0f77e531b6b530b0edda",
    name: 'Charlie',
    office: {
      code: 'OB123456'
      // some other fields
    }
  },
  {
    _id: "5b7d0f73e531b6b530b0ee5b",
    name: 'Bill',
    office: {
      code: 'EE858758'
    }
  },
  {
    _id: "5b7d0f77e531b6b530b0ee5n",
    name: 'Echo',
    office: {
      code: 'OB123456'
    }
  },
];

我正在研究猫鼬聚合,只是尝试过

await Employee.aggregate([
      {
        $lookup: {
          from: 'offices',
          localField: 'office.code',
          foreignField: 'code',
          as: 'officeCode'
        },
        $group: {
          _id: 'officeCode.city',
          count: { $sum: 1 }
        }
      }
    ]);

这肯定行不通,我尝试阅读一些聚合文档,但无法提出如何完成此操作的好主意

提前感谢您的任何建议或意见。

我正在寻找的样本输出

{
    "Vancouver": 1,
    "Canmore": 2
}

【问题讨论】:

    标签: javascript mongoose count aggregation-framework


    【解决方案1】:

    您必须从办公室而不是员工开始,因此您可以为每个区域(城市)创建一个代码列表,然后查找与您的员工进行映射。

    db.office.aggregate([
      {
        $group: {
          _id: "$city",
          codes: {
            $addToSet: "$code"
          }
        }
      },
      {
        $lookup: {
          from: "employee",
          localField: "codes",
          foreignField: "office.code",
          as: "employees"
        },
        
      },
      {
        $group: {
          _id: null,
          data: {
            $push: {
              k: "$_id",
              v: {
                $size: "$employees"
              }
            }
          }
        }
      },
      {
        $replaceRoot: {
          newRoot: {
            "$arrayToObject": "$data"
          }
        }
      }
    ])
    

    最后两个阶段仅用于按照预期输出中的描述格式化结果。

    You can test it here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-10
      • 2018-02-24
      • 2015-05-19
      • 2020-08-14
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多