MongoDB聚合查询:排序后为结果添加序号虚拟字段
解决方案
要实现排序后为每个文档添加从1开始的递增序号,你需要使用MongoDB的$setWindowFields聚合阶段(MongoDB 5.0及以上版本支持),替代原来的$addFields。这个阶段可以基于排序后的结果集生成行号,直接满足你的需求。
修改后的完整聚合查询如下:
db.getCollection('callqueues').aggregate([ { $match: { 'invalidated': false, 'assigned_agent': null } }, { $sort: { score: -1, _id: -1 } }, { $setWindowFields: { partitionBy: null, // 将整个查询结果作为单个分区 sortBy: { score: -1, _id: -1 }, // 与之前的排序规则保持一致 output: { order: { $rowNumber: {} // 生成从1开始的递增序号 } } } } ])
关键部分说明
$setWindowFields:专门用于窗口函数计算的聚合阶段,能基于排序后的数据集生成序号这类上下文相关的字段。partitionBy: null:表示不拆分分区,把所有排序后的文档当成一个整体来计算序号。sortBy:必须和前面$sort的规则完全一致,确保序号是基于你想要的排序结果生成的。$rowNumber: {}:内置窗口函数,会为每个文档生成从1开始的连续整数,正好对应你需要的显示顺序编号。
如果你的MongoDB版本低于5.0,可以用$group+$unwind的方式实现:
db.getCollection('callqueues').aggregate([ { $match: { 'invalidated': false, 'assigned_agent': null } }, { $sort: { score: -1, _id: -1 } }, { $group: { _id: null, docs: { $push: "$$ROOT" } } }, { $unwind: { path: "$docs", includeArrayIndex: "order" } }, { $replaceRoot: { newRoot: { $mergeObjects: ["$docs", { order: { $add: ["$order", 1] } }] } } } ])
这个旧版本方案的逻辑是先把所有文档聚合到一个数组里,再展开数组并获取数组索引,最后把索引加1(因为数组索引从0开始)得到从1开始的序号。
内容的提问来源于stack exchange,提问作者Ben Perram
相关产品推荐
相关产品推荐

