如何用MongoDB聚合将同分类新闻按hot拆分并按date排序
MongoDB聚合拆分筛选结果并排序的实现方案
完整聚合管道代码
针对你的需求,在现有$match筛选的基础上,添加对应聚合阶段即可实现目标格式:
方案一(MongoDB 5.2+ 推荐)
const newsData = await Db.Collection.aggregate([ // 保留原有的分类筛选逻辑 { $match: { "category.name": '123' } }, // 按hot字段拆分文档到两个数组 { $group: { _id: null, hotNews: { $push: { $cond: [ { $eq: ["$hot", true] }, "$$ROOT", "$$REMOVE" ] } }, news: { $push: { $cond: [ { $eq: ["$hot", false] }, "$$ROOT", "$$REMOVE" ] } } } }, // 对两个数组分别按date排序 { $project: { _id: 0, hotNews: { $sortArray: { input: "$hotNews", sortBy: { date: 1 } } }, // 1为升序,-1为降序,按需调整 news: { $sortArray: { input: "$news", sortBy: { date: 1 } } } } } ]).toArray(); // 取结果数组第一个元素即为目标格式 const finalResult = newsData[0];
方案二(兼容MongoDB 5.2以下版本)
如果你的MongoDB版本不支持$sortArray,可以先排序再分组:
const newsData = await Db.Collection.aggregate([ { $match: { "category.name": '123' } }, // 先按hot和date排序,确保分组后数组有序 { $sort: { hot: -1, date: 1 } }, { $group: { _id: null, hotNews: { $push: { $cond: [ { $eq: ["$hot", true] }, "$$ROOT", "$$REMOVE" ] } }, news: { $push: { $cond: [ { $eq: ["$hot", false] }, "$$ROOT", "$$REMOVE" ] } } } }, { $project: { _id: 0 } } ]).toArray(); const finalResult = newsData[0];
各阶段说明
- $match阶段:维持原有的筛选逻辑,仅保留
category.name为'123'的文档。 - $group阶段:通过
_id: null将所有筛选后的文档归为一组,使用$push结合$cond条件判断,分别收集hot为true和false的文档,$$REMOVE会自动过滤不符合条件的条目,避免数组中出现null值。 - 排序处理:
- 方案一用
$sortArray直接对分组后的数组按date字段排序,语法更直观; - 方案二先通过
$sort对所有文档排序,再分组时自然得到有序数组,兼容旧版本MongoDB。
- 方案一用
内容的提问来源于stack exchange,提问作者Joyce
相关产品推荐
相关产品推荐

