如何基于_id是否在关注ID数组中对MongoDB用户文档进行排序
实现方案
可以通过MongoDB聚合查询的权重计算逻辑实现已关注用户优先排序,不需要过滤未关注用户,以下是适配Node.js + Mongoose 技术栈的具体实现:
方案1:先查关注ID数组再聚合(适合关注数不多的场景)
你已经可以拿到当前用户关注的ID数组,直接通过$addFields添加临时排序权重字段即可:
// 1. 查询当前用户的关注ID数组 const followedRecords = await Follow.find( { follower: currentUserId }, // currentUserId为发起请求的当前用户ID { followee: 1, _id: 0 } ); const followedUserIds = followedRecords.map(item => item.followee); // 2. 聚合查询用户列表并排序 const sortedUsers = await User.aggregate([ // 可在此处添加你自己的过滤条件,比如用户名搜索等,无相关需求可省略 // { $match: { username: { $regex: searchKey, $options: 'i' } } }, // 新增排序权重字段:已关注用户权重为1,未关注为0 { $addFields: { sortWeight: { $cond: { if: { $in: ['$_id', followedUserIds] }, then: 1, else: 0 } } } }, // 按权重倒序排列,已关注的排在前面;可追加其他排序规则,比如按注册时间倒序 { $sort: { sortWeight: -1, createdAt: -1 } }, // 可选:移除不需要返回的权重字段 { $project: { sortWeight: 0 } } ]);
方案2:联表聚合查询(适合关注数特别大的场景)
如果用户关注数超过1000,推荐直接在聚合管道中关联follows集合计算权重,避免传输大数组的性能损耗:
const sortedUsers = await User.aggregate([ // 关联follows集合,查询当前用户和对应用户的关注关系 { $lookup: { from: 'follows', // 此处填MongoDB中follows的实际集合名,默认是模型名小写+s let: { userId: '$_id' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$follower', currentUserId] }, { $eq: ['$followee', '$$userId'] } ] } } }, { $limit: 1 } ], as: 'followRelation' } }, // 计算排序权重 { $addFields: { sortWeight: { $cond: { if: { $gt: [{ $size: '$followRelation' }, 0] }, then: 1, else: 0 } } } }, // 排序 { $sort: { sortWeight: -1, createdAt: -1 } }, // 移除多余字段 { $project: { sortWeight: 0, followRelation: 0 } } ]);
注意事项
- 要保证
followedUserIds数组中的ID类型和users集合的_id类型一致,不要混用字符串类型和MongooseObjectId类型,否则$in判断会失效 - 两种方案均不会过滤未关注用户,仅调整排序顺序,符合需求
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

