【问题标题】:MongoDB group by aggregation queryMongoDB按聚合查询分组
【发布时间】:2021-05-19 02:53:39
【问题描述】:

我掌握的数据是:

[
    { type: 'software' },
    { type: 'hardware' },
    { type: 'software' },
    { type: 'network' },
    { type: 'test' },
    ...
]

我想通过聚合管道创建一个 MongoDB 组以返回如下数据: 我只想要结果中的 3 个对象 结果中的第三个对象 {_id: 'other', count: 2}, 这应该是软件和硬件以外类型的计数总和

[
    {_id: 'software', count: 2},
    {_id: 'hardware', count: 1},
    {_id: 'other', count: 2},
]

【问题讨论】:

  • 这些数据是存储在单个文档的字段中,还是存储在单独的文档中?
  • @AlexZeDim 这些是单独的文档。
  • 您可能想通过按评分下方的绿色标记来检查并接受我的答案(如果我的答案正确,可能还会投票)
  • 我更新了我的查询,您可以再次查看结果。

标签: node.js mongodb group-by pipeline aggregation


【解决方案1】:

这是the exact query (MongoPlayground),如果这些数据是单独的文档,您需要它。只需在组之前添加$project 阶段,然后添加$switch 运算符。 (如果这些字段数据是数字,你可能想检查$bucket

db.collection.aggregate([
  {
    "$project": {
      type: {
        "$switch": {
          "branches": [
            {
              "case": {
                "$eq": [
                  "$type",
                  "software"
                ]
              },
              "then": "software"
            },
            {
              "case": {
                "$eq": [
                  "$type",
                  "hardware"
                ]
              },
              "then": "hardware"
            }
          ],
          default: "other"
        }
      }
    }
  },
  {
    "$group": {
      "_id": "$type",
      "count": {
        "$sum": 1
      }
    }
  }
])

另外,我建议避免使用字段名称type。实际上它并没有在 MongoDB 中保留,但是它可能会与某些驱动程序发生冲突,因为在模式/模型文件中,类型字段是指该字段的确切 BSON 类型。

【讨论】:

  • 这不起作用,因为结果中的第三个对象 {_id: 'other', count: 2},这应该是软件和硬件以外的类型的计数总和。
  • 查询的结果是 [ { "_id": "test", "count": 1 }, { "_id": "network", "count": 1 }, { “_id”:“软件”,“计数”:2 },{“_id”:“硬件”,“计数”:1 }]
  • 哦,那个,然后用这样的澄清更新问题,我会更新我的答案,你绝对确定,你需要聚合框架,而不是 3 个单独的请求?最好并行执行 3 个请求,而不是使用 $switch
  • 你不觉得3个请求会花费更多时间来得到结果吗?您是否建议使用 $facet(聚合)?
  • @sandy 在这种情况下使用$facet 我猜是“太多”了。我在考虑Promise.all[queries] 中的.find,但我重新思考了自己的想法和猜测,如果你的收藏是有阴影的,countDocumentsEsp 不可能是一个选择。