首页 > 解决方案 > 猫鼬子查询中子文档的计数值

问题描述

我有一组看起来像这样的文档:

[
  { group_id: 1, value: 'foo' },
  { group_id: 1, value: 'bar' },
  { group_id: 1, value: 'bar' },
  { group_id: 1, value: 'bar' },
  { group_id: 2, value: 'bar' },
  { group_id: 2, value: 'foo' },
  { group_id: 2, value: 'foo' },
  { group_id: 2, value: 'foo' }
]

对于每个group_id我想返回出现最多的值。所以我的输出应该是这样的......

[
  { group_id: 1, maxValue: 'bar', maxValueCount: 3 },
  { group_id: 2, maxValue: 'foo', maxValueCount: 3 }
]

你会如何使用 Mongoose 聚合函数来做到这一点?

更新:据我所知,我现在只需要返回最大计数的值......

const records = await Record.aggregate([
  {
    $group: {
        _id: {
            id: '$group_id',
            value: '$value'
    },
    count: { $sum: 1 }
  }
}
])

标签: node.jsmongodbmongoose

解决方案


您可以通过以下方式实现您的目标

  • 按 group_id/value 分组(并计算 value 的出现次数)
  • 然后按 group_id 分组并将所有找到的值与它们的计数一起推送
  • 最后从数组中保留具有最大计数的值
data=[
  { group_id: 1, value: 'foo' },
  { group_id: 1, value: 'bar' },
  { group_id: 1, value: 'bar' },
  { group_id: 1, value: 'bar' },
  { group_id: 1, value: 'bar' },//one more added
  { group_id: 2, value: 'bar' },
  { group_id: 2, value: 'foo' },
  { group_id: 2, value: 'foo' },
  { group_id: 2, value: 'foo' }
]

db.products.remove({})
db.products.insert(data)

const stages = [
{
  $group: {
    _id: {
      group_id: '$group_id',
      value: '$value'
    },
    n: { $sum: 1 }
  }
},
{
  $group: {
    _id: '$_id.group_id',
    values: {
      $push: {
        value: '$_id.value',
        n: '$n'
      }
    }
  }
},
{
  $project: {
    group_id:1,
    best: {
      $reduce: {
        input: '$values',
        initialValue: { n: 0, value: ''},
        in: {
          $cond: [
            {
              $lt: ['$$value.n', '$$this.n']
            },
            '$$this',
            '$$value'
          ]
        }
      }
    }
  },
},
{
  $project: {
    group_id: 1,
    value: '$best.value',
    maxValue: '$best.n'
  }
}
]
printjson(db.products.aggregate(stages).toArray())

操场


推荐阅读