You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 05:21:01