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

MongoDB聊天应用聚合查询问题:获取单对话最新消息

解决聊天应用中获取单对话最新消息的聚合查询问题

问题原因

你的聚合查询返回两条消息,是因为分组时用{sender: "$sender", receiver: "$receiver"}作为_id,这会把UserX→UserY和UserY→UserX当成两个独立对话分组,但实际上这属于同一个双向对话。

解决方案

核心是给每个对话生成唯一统一标识:将对话涉及的两个用户ID按固定顺序(比如ObjectId字符串排序)组成数组作为分组键,这样无论消息发送方向如何,同个对话都会被归为一组。

修改后的聚合查询代码

const Chats = await Message.aggregate([
    // 过滤当前用户参与的所有消息
    {
        $match: {
            $or: [
                { sender: mongoose.Types.ObjectId(req.user.id) },
                { receiver: mongoose.Types.ObjectId(req.user.id) }
            ]
        }
    },
    // 生成对话统一标识:将两个用户ID排序后组成数组
    {
        $addFields: {
            conversationKey: {
                $sortArray: {
                    input: ["$sender", "$receiver"],
                    sortBy: 1
                }
            }
        }
    },
    // 按创建时间倒序,确保最新消息排在最前
    { $sort: { createdAt: -1 } },
    // 按统一标识分组,取每组第一条(最新)消息
    {
        $group: {
            _id: "$conversationKey",
            latestMessage: { $first: "$$ROOT" }
        }
    },
    // 替换为最新消息内容
    { $replaceWith: "$latestMessage" },
    // 可选:关联用户信息,方便前端展示聊天对象详情
    {
        $lookup: {
            from: "users",
            localField: "sender",
            foreignField: "_id",
            as: "senderInfo"
        }
    },
    {
        $lookup: {
            from: "users",
            localField: "receiver",
            foreignField: "_id",
            as: "receiverInfo"
        }
    },
    { $unwind: "$senderInfo" },
    { $unwind: "$receiverInfo" }
]);

代码说明

  1. $match阶段:直接通过sender或receiver匹配当前用户,比依赖usersRelated更可靠,避免数组维护错误。
  2. $addFields阶段:用$sortArray对两个用户ID排序,生成统一的conversationKey,确保同对话的消息分组一致。
  3. $sort阶段:按createdAt倒序,保证分组后$first能取到最新消息。
  4. $group阶段:以conversationKey为分组键,用$first获取每组的第一条(最新)消息。
  5. 可选$lookup阶段:关联用户集合,获取发送方/接收方的昵称、头像等信息,满足前端展示需求。

效果验证

针对你提供的两条测试消息,执行上述查询后,两条消息会被归为同一组,最终返回"Good thanks, and you?"这条最新消息,符合主流聊天应用的聊天列表展示逻辑。

内容的提问来源于stack exchange,提问作者Technosha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 21:30:04