MongoDB如何按角色分组统计掷骰结果,替代$group中不可用的$sortByCount?
问题原因
$sortByCount是MongoDB的顶级聚合管道阶段,只能作为管道的独立节点使用,不能嵌套在$group的累加器配置中,所以你原来的写法会报错。
最优实现方案
不需要提前枚举任何outcome类型,就能自动统计每个角色所有掷骰结果的计数,完整聚合管道如下:
db.characters.aggregate([ // 原有关联掷骰日志的逻辑保持不变 { $lookup: { from: 'roll_stats', localField: '_id', foreignField: 'charid', as: 'roll' } }, { $unwind: '$roll' }, // 按「角色+掷骰结果」双维度分组,统计单个结果的出现次数 { $group: { _id: { charId: '$_id', charName: '$name', outcome: '$roll.outcome' }, count: { $sum: 1 } } }, // 可选:如果需要按计数降序排序,和$sortByCount效果一致,加这个阶段 { $sort: { count: -1 } }, // 按角色维度合并,收集所有结果的计数为数组 { $group: { _id: { charId: '$_id.charId', charName: '$_id.charName' }, outcomes: { $push: { k: '$_id.outcome', v: '$count' } } } }, // 可选:如果需要outcomes为对象格式(修正你示例中数组写键值对的语法问题),加这个转换阶段 { $set: { outcomes: { $arrayToObject: '$outcomes' } } }, // 字段映射输出 { $project: { _id: 0, character: '$_id.charName', outcomes: 1 } } ])
输出说明
- 不加
$arrayToObject阶段时,outcomes为数组结构,每个元素格式为{ "k": "critical", "v": 8 },可以修改$push的配置自定义字段名,比如改成{ outcome: '$_id.outcome', count: '$count' }更易读。 - 加
$arrayToObject阶段时,outcomes为对象结构,格式和你预期的键值对完全一致:{ "critical": 8, "success": 32 }。
内容的提问来源于stack exchange,提问作者tiltowait
相关产品推荐
相关产品推荐

