MongoDB聚合如何获取最后一个已定义status值且保留最新data值
实现方案
你可以通过先收集所有非空的status值再取最新值的方式实现需求,完整代码如下:
const project = await collection.aggregate([ { $match: { projectId: id } }, // 按时间升序排序,保证最新文档排在列表末尾,若有自定义创建时间字段可替换为对应字段 { $sort: { _id: 1 } }, { $group: { _id: '$projectId', // 仅收集存在且非空的status,按时间顺序存入数组 validStatusList: { $push: { $cond: [ { $and: [ { $ne: [ "$status", undefined ] }, { $ne: [ "$status", null ] } // 如果需要额外过滤空字符串,可再加条件:{ $ne: [ "$status", "" ] } ] }, "$status", "$$REMOVE" ] } }, // 直接取最新文档的data字段,逻辑保持不变 data: { $last: '$data' } } }, // 提取有效status数组的最后一位,即为最近的非空status值 { $project: { _id: 1, data: 1, status: { $last: '$validStatusList' } } } ]).toArray();
逻辑说明
- 必须先对匹配到的文档按时间维度排序,才能保证
$last、$push操作的顺序符合时间先后要求,无自定义时间字段时可直接用_id排序,MongoDB的ObjectId自带时间戳属性。 $cond判断中使用$$REMOVE系统变量,不符合条件的status不会被推入validStatusList数组,避免数组中出现空值。- 最终
validStatusList数组的最后一位就是最近存在的非空status值,同时保留了最新文档的data字段。
内容的提问来源于stack exchange,提问作者kgommers
相关产品推荐
相关产品推荐

