如何按指定规则对MongoDB中Dialogs文档的字符串数组排序
MongoDB Dialogs集合自定义排序方案
可以通过聚合管道先计算每个文档的排序权重,再按权重升序排列来实现需求。核心思路是根据members数组的元素特征,为每个文档分配对应的优先级分数,分数越小排序越靠前。
具体聚合操作代码
db.Dialogs.aggregate([ { $addFields: { sortPriority: { $switch: { branches: [ // 1. 仅包含admin和all(长度为2,含all) { case: { $and: [ { $eq: [{ $size: "$members" }, 2] }, { $in: ["all", "$members"] } ] }, then: 1 }, // 2. 包含all和group(含all,同时有group_开头的元素) { case: { $and: [ { $in: ["all", "$members"] }, { $gt: [{ $size: { $filter: { input: "$members", cond: { $regexMatch: { input: "$$this", regex: "^group_" } } } }, 0] } ] }, then: 2 }, // 3. 仅包含admin和group(长度2,含group_开头元素,无all) { case: { $and: [ { $eq: [{ $size: "$members" }, 2] }, { $gt: [{ $size: { $filter: { input: "$members", cond: { $regexMatch: { input: "$$this", regex: "^group_" } } } }, 0] }, { $not: { $in: ["all", "$members"] } } ] }, then: 3 }, // 4. 包含group和user(同时有group_和user_开头元素,无all) { case: { $and: [ { $gt: [{ $size: { $filter: { input: "$members", cond: { $regexMatch: { input: "$$this", regex: "^group_" } } } }, 0] }, { $gt: [{ $size: { $filter: { input: "$members", cond: { $regexMatch: { input: "$$this", regex: "^user_" } } } }, 0] }, { $not: { $in: ["all", "$members"] } } ] }, then: 4 }, // 5. 仅包含admin和user(长度2,含user_开头元素,无all、group) { case: { $and: [ { $eq: [{ $size: "$members" }, 2] }, { $gt: [{ $size: { $filter: { input: "$members", cond: { $regexMatch: { input: "$$this", regex: "^user_" } } } }, 0] }, { $not: { $in: ["all", "$members"] } }, { $eq: [{ $size: { $filter: { input: "$members", cond: { $regexMatch: { input: "$$this", regex: "^group_" } } } }, 0] } ] }, then: 5 } ], default: 6 // 兜底处理不符合上述情况的文档 } } } }, { $sort: { sortPriority: 1 } }, { $project: { sortPriority: 0 } } // 可选:移除排序权重字段 ])
代码说明
$addFields阶段:通过$switch和一系列条件判断,给每个文档分配sortPriority分数,分数对应需求中的排序顺序。- 使用
$size判断数组长度,结合$in检查是否包含特定元素。 - 通过
$filter+$regexMatch筛选出group_或user_开头的元素,判断是否存在这类成员。
- 使用
$sort阶段:按sortPriority升序排列,分数越小的文档越靠前。$project阶段:可选操作,用于移除临时添加的sortPriority字段,返回原始文档结构。
内容的提问来源于stack exchange,提问作者Mykhailo Yeromin
相关产品推荐
相关产品推荐

