如何通过单个MongoDB查询获取总计数及不同排序首条文档
MongoDB 单聚合实现方案
可以通过$facet多面聚合一次性完成三个逻辑,只需要一次集合扫描,效率比三次独立查询高很多,最终输出结构完全匹配需求。
聚合管道各阶段逻辑:
- 第一阶段
$match:传入已有的myFilter条件,先过滤出所有符合要求的文档,和原find查询的筛选逻辑完全一致 - 第二阶段
$facet:在过滤后的文档集上并行执行三个独立的子处理逻辑,互不干扰 - 第三阶段
$project:调整子管道返回的数组结构,把嵌套的数组值拆成要求的字段格式,同时做空值兜底
完整可直接运行的代码如下:
db.xyz.aggregate([ { $match: myFilter }, { $facet: { item_1: [ { $sort: mySort1 }, { $limit: 1 } ], item_2: [ { $sort: mySort2 }, { $limit: 1 } ], totalCount: [ { $count: "val" } ] } }, { $project: { item_1: { $ifNull: [{ $first: "$item_1" }, null] }, item_2: { $ifNull: [{ $first: "$item_2" }, null] }, totalCount: { $ifNull: [{ $first: "$totalCount.val" }, 0] } } } ])
性能提示:如果筛选后的数据集量级较大,建议提前给
mySort1、mySort2的排序字段和筛选字段建立对应复合索引,避免聚合触发内存排序,执行速度会和单独跑三个带索引的查询基本一致,还能省下多次查询的网络开销和重复扫描开销。如果没有匹配
myFilter的文档,返回结果中item_1、item_2为null,totalCount为0,符合常规业务预期。
内容的提问来源于stack exchange,提问作者diziaq
相关产品推荐
相关产品推荐

