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

Mongoose分组联查实现类似WhatsApp首页的会话用户列表查询

Mongoose 实现会话列表查询方案

完整实现代码

const mongoose = require('mongoose');
const Message = require('./models/message'); // 替换为你实际的Message模型引入路径

async function getUserChatList(currentUserId) {
  // 转换为ObjectId类型避免匹配失败
  const targetUserId = new mongoose.Types.ObjectId(currentUserId);

  const rawChatList = await Message.aggregate([
    // 1. 过滤所有和当前用户相关的收发消息
    {
      $match: {
        $or: [
          { from: targetUserId },
          { to: targetUserId }
        ]
      }
    },
    // 2. 按发送时间倒序排列,保证最新消息在分组时排在首位
    {
      $sort: { date: -1 }
    },
    // 3. 生成会话唯一标识、标记聊天对方
    {
      $addFields: {
        // 将两个用户ID按大小排序后拼接,保证互发消息归为同一个会话
        sessionKey: {
          $concat: [
            { $toString: { $min: ["$from", "$to"] } },
            "-",
            { $toString: { $max: ["$from", "$to"] } }
          ]
        },
        // 识别当前会话的对方用户ID
        contactUser: {
          $cond: {
            if: { $eq: ["$from", targetUserId] },
            then: "$to",
            else: "$from"
          }
        }
      }
    },
    // 4. 按会话分组,每个会话只保留最新一条消息
    {
      $group: {
        _id: "$sessionKey",
        latestMessage: { $first: "$$ROOT" },
        contactUser: { $first: "$contactUser" }
      }
    },
    // 可选:调整返回结构,更贴合前端使用习惯
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: ["$latestMessage", { contactUser: "$contactUser" }]
        }
      }
    }
  ]);

  // 手动populate关联的用户信息,支持from、to、对方用户三个字段的关联查询
  const populatedChatList = await Message.populate(rawChatList, [
    { path: "from", model: "Users" },
    { path: "to", model: "Users" },
    { path: "contactUser", model: "Users" }
  ]);

  return populatedChatList;
}

优化建议

  • 给from、to、date三个字段添加联合索引,数据量大时查询性能可提升数倍
  • 如果不需要完整消息字段,可在$group阶段仅保留需要的messageContent、date、status等字段,减少数据传输开销
  • 可额外添加未读消息统计逻辑,在$group阶段用$sum统计未读消息数量即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:06:04