MongoDB聚合:按子文档日期筛选每个用户的目标文档
MongoDB聚合解决方案:筛选每个用户最近一次Clubs游戏的文档
假设你的userresults文档结构类似这样:
{ "_id": ObjectId("..."), "userref": "AAA", "sessionref": "S1", "results": [ {"game": "Clubs", "date": ISODate("2024-01-01T00:00:00Z"), ...}, {"game": "Hearts", "date": ISODate("2024-01-01T01:00:00Z"), ...} ] }, { "_id": ObjectId("..."), "userref": "AAA", "sessionref": "S2", "results": [ {"game": "Clubs", "date": ISODate("2024-01-02T00:00:00Z"), ...}, {"game": "Spades", "date": ISODate("2024-01-02T01:00:00Z"), ...} ] }, { "_id": ObjectId("..."), "userref": "BBB", "sessionref": "S1", "results": [ {"game": "Clubs", "date": ISODate("2024-01-03T00:00:00Z"), ...} ] }
完整聚合管道代码
db.userresults.aggregate([ // 1. 提取当前文档中Clubs游戏的最新日期 { $addFields: { latestClubsDate: { $max: { $map: { input: { $filter: { input: "$results", cond: { $eq: ["$$this.game", "Clubs"] } } }, as: "clubResult", in: "$$clubResult.date" } } } } }, // 2. 按userref分组,记录每个用户的最大Clubs日期及所有关联文档 { $group: { _id: "$userref", maxClubsDate: { $max: "$latestClubsDate" }, docs: { $push: { fullDoc: "$$ROOT", latestClubsDate: "$latestClubsDate" } } } }, // 3. 筛选出对应用户最大Clubs日期的目标文档 { $addFields: { targetDoc: { $first: { $filter: { input: "$docs", cond: { $eq: ["$$this.latestClubsDate", "$maxClubsDate"] } }.fullDoc } } } }, // 4. 将目标文档设为根文档,输出完整结构 { $replaceRoot: { newRoot: "$targetDoc" } }, // 可选:清理临时生成的latestClubsDate字段 { $project: { latestClubsDate: 0 } } ])
关键步骤说明
- 步骤1:从每个文档的
results数组中过滤出Clubs游戏记录,提取它们的日期并取最大值,得到该文档内Clubs游戏的最新时间。 - 步骤2:按
userref分组,计算每个用户所有文档中最大的Clubs日期,同时把用户的所有文档信息存入数组备用。 - 步骤3:从用户的文档数组中,筛选出Clubs日期等于用户最大日期的文档,确保只保留最近一次的那条记录。
- 步骤4:将筛选出的目标文档转为顶层输出结构,得到最终需要的结果。
如果你的results数组中每个文档的Clubs游戏只有一条,可省略步骤1中的$max,直接取过滤后第一条记录的日期即可。
内容的提问来源于stack exchange,提问作者EricP
相关产品推荐
相关产品推荐

