MongoDB聚合查询实现多用户各取5条降序文件数据
用MongoDB聚合实现批量获取用户的前N条文件数据
针对你的需求,直接用files集合的聚合管道就能高效完成,不需要循环查询。以下是完整的聚合查询代码,适配你指定的用户ID列表,返回每个用户最多5条按at字段降序排列的文件ID:
db.files.aggregate([ // 筛选目标用户的文件,缩小处理范围 { $match: { userID: { $in: ["user1", "user2", "user5"] } } }, // 按at字段降序排序,确保最新文件优先 { $sort: { at: -1 } }, // 按用户分组,收集文件ID并截取前5条 { $group: { _id: "$userID", fileIDs: { $slice: [ { $push: "$_id" }, 5 ] } } }, // 调整结构为用户ID映射文件数组的格式 { $project: { _id: 0, userFileMap: { $arrayToObject: [[{ k: "$_id", v: "$fileIDs" }]] } } }, // 展开为最终的键值对输出 { $replaceRoot: { newRoot: "$userFileMap" } } ])
各阶段说明:
- $match:先过滤出目标用户的文件,避免处理无关数据,大幅提升查询效率。
- $sort:按
at字段降序排序,保证每个用户的文件按需求顺序排列。 - $group:按
userID分组,用$push收集文件ID为数组,再用$slice截取前5条,确保每个用户最多返回5条数据。 - $project + $replaceRoot:把分组结果转换成你期望的
{ "user1": [fileIDs...] }格式。
扩展:关联users集合获取用户
如果你的用户ID列表不是硬编码,而是需要从users集合读取(比如取前15个用户),可以用$lookup关联集合,调整后的管道如下:
db.users.aggregate([ // 获取目标用户(示例取前15个) { $limit: 15 }, // 关联files集合获取用户文件 { $lookup: { from: "files", localField: "_id", foreignField: "userID", as: "userFiles" } }, // 对用户文件按at降序排序并截取前5条 { $addFields: { userFiles: { $slice: [ { $sortArray: { input: "$userFiles", sortBy: { at: -1 } } }, 5 ] } } }, // 提取文件ID并转为键值对格式 { $project: { _id: 0, userFileMap: { $arrayToObject: [[{ k: "$_id", v: "$userFiles._id" }]] } } }, { $replaceRoot: { newRoot: "$userFileMap" } } ])
这种方式完全避免了循环查询的N+1问题,所有逻辑在MongoDB端一次性完成,网络开销和查询效率都远优于原来的循环写法。
内容的提问来源于stack exchange,提问作者Tom3652
相关产品推荐
相关产品推荐

