MongoDB聚合查询问题:按用户分组筛选错题超对题3倍的知识点
解决方案
你的核心问题是分组逻辑错误——你把单个文档里的acertos、erros直接放到了分组_id中,导致无法对同一用户、同一知识点的数值进行累加。以下是修正后的聚合语句,完全匹配你的需求:
db.collection.aggregate([ // 展开嵌套的学科数组 { $unwind: "$materias" }, // 展开每个学科下的知识点数组 { $unwind: "$materias.assuntos" }, // 按用户ID和知识点名称分组,累加总对题数和总错题数 { $group: { _id: { uid: "$user.uid", assuntoNome: "$materias.assuntos.nome" }, totalAcertos: { $sum: "$materias.assuntos.acertos" }, totalErros: { $sum: "$materias.assuntos.erros" } } }, // 筛选符合条件的知识点:错题≥3,且错题≥对题数的3倍 { $match: { totalErros: { $gte: 3 }, $expr: { $gte: ["$totalErros", { $multiply: ["$totalAcertos", 3] }] } } }, // 可选:重新整理输出格式,按用户ID分组,列出需提升的知识点列表 { $group: { _id: "$_id.uid", needImproveAssuntos: { $push: "$_id.assuntoNome" } } } ])
步骤说明:
- $unwind阶段:连续展开
materias和materias.assuntos嵌套数组,将每个知识点拆分为独立文档,为后续分组统计做准备。 - 第一次$group阶段:以
user.uid(用户ID)和assuntos.nome(知识点名称)作为分组维度,用$sum累加同用户、同知识点的所有对题数和错题数,得到该用户在对应知识点下的总数据。 - $match阶段:筛选满足双条件的结果:
- 总错题数
totalErros≥3 - 总错题数≥总对题数的3倍(通过
$expr支持聚合表达式的逻辑比较)
- 总错题数
- 可选的第二次$group阶段:将同一用户的所有需提升知识点整合为列表,便于直接展示使用。
原语句失败原因:
- 你将单个文档的
acertos、erros值放入分组_id,导致分组维度变成了「用户+知识点+单条记录的对错数」,无法实现跨记录的累加统计。 - 在分组
_id中嵌入$cond逻辑是错误用法,分组键仅用于定义分组维度,不能包含条件判断或计算逻辑。
内容的提问来源于stack exchange,提问作者DAVI FONSECA
相关产品推荐
相关产品推荐

