MongoDB聚合统计用户帖子数 无结果时返回默认值0
问题原因
原聚合返回空数组是$count的固有特性:当输入文档为空时,$count不会输出任何文档,最终聚合结果就是空数组。另外你写的时间计算逻辑有bug:第一次执行setHours后start被赋值为数字类型的时间戳,后续对数字调用setHours会直接报错。
实现方案
使用$facet阶段包裹统计逻辑即可保证无论是否有匹配数据,都能返回固定结构的结果,修改后的完整聚合代码如下:
// 先修正时间计算逻辑 const start = new Date() start.setHours(0, 0, 0, 0) const end = new Date() end.setHours(23, 59, 59, 999) model.aggregate([ { $match: { userId, createdAt: { $gte: start, $lt: end } } }, { $unwind: '$posts' }, { $facet: { countResult: [ { $count: 'total' } ] } }, { $project: { total: { $ifNull: [ { $arrayElemAt: ['$countResult.total', 0] }, 0 ] }, _id: 0 } } ])
逻辑说明
$facet支持在同一输入文档集上运行多个独立的子聚合管道,即使前置阶段过滤后没有任何剩余文档,$facet也固定返回1条结果文档,从根源避免返回空数组的问题。- 子管道内沿用原来的
$count逻辑统计帖子总数,有匹配数据时countResult数组会存储统计结果,无匹配时为空数组。 - 最后通过
$project配合$arrayElemAt取出统计值,用$ifNull将空值场景默认赋值为0,输出格式完全符合预期。
补充说明:如果你实际需要过滤的是帖子本身的创建时间,而非父级文档的创建时间,请在
$unwind后新增$match阶段,对posts.createdAt做时间范围过滤即可。
内容的提问来源于stack exchange,提问作者Beginner
相关产品推荐
相关产品推荐

