MongoDB如何按对话分组获取用户唯一会话列表及最新消息时间
解决方法
你可以通过以下修改后的聚合语句实现需求,核心逻辑是先提取会话的对方ID,再按对方ID分组取最新消息时间,最后转换为你需要的键值对格式:
const targetUserId = "1"; // 要查询的目标用户ID [ // 第一步:筛选所有和目标用户相关的消息 { "$match": { "$or": [ { "who": targetUserId }, { "whom": targetUserId } ] } }, // 第二步:生成会话对方的ID字段,过滤掉自身 { "$project": { "peer": { "$cond": { "if": { "$eq": [ "$who", targetUserId ] }, "then": "$whom", "else": "$who" } }, "when": 1 } }, // 第三步:按对方ID分组,取该会话最新的消息时间 { "$group": { "_id": "$peer", "latestWhen": { "$max": "$when" } } }, // 第四步:可选,转换为你需要的 {对方ID: 最新时间} 的对象格式 { "$group": { "_id": null, "result": { "$push": { "k": "$_id", "v": "$latestWhen" } } } }, { "$replaceRoot": { "newRoot": { "$arrayToObject": "$result" } } } ]
分步说明
- 第一步
$match和原有逻辑一致,仅保留目标用户作为发送方或接收方的所有消息 - 第二步
$project通过条件判断提取会话的另一方ID:如果当前消息是目标用户发的,对方就是whom,否则对方就是who,同时保留消息时间字段 - 第三步
$group按对方ID聚合,用$max运算符取出该会话下最新的消息时间 - 最后两步是可选的格式转换,如果你不需要严格的键值对对象,只需要数组格式的结果,完全可以省略最后两步,得到的结构为
[{"_id": "2", "latestWhen": MSG_DATE2}, {"_id": "3", "latestWhen": MSG_DATE3}],业务层处理起来也很方便
用你给出的测试数据执行后,就会直接得到你要求的输出格式:
{ "2": MSG_DATE2, "3": MSG_DATE3 }
内容的提问来源于stack exchange,提问作者Max Frai
相关产品推荐
相关产品推荐

