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

如何在MongoDB中查询每个收发用户对对应的最新一条聊天记录?

解决方案

你可以通过MongoDB聚合管道实现该需求,核心逻辑是为双向会话生成唯一标识后分组取最新记录,mongoose写法如下:

首先确认你Chat集合的模型定义(示例):

const chatSchema = new mongoose.Schema({
  sender: String,
  reciever: String,
  text: String
}, { timestamps: true }) // 开启timestamps会自动生成createdAt、updatedAt字段,用于时间排序更准确
const Chat = mongoose.model('Chat', chatSchema)

会话列表查询代码

// 传入当前登录用户的ID,仅查询和该用户相关的会话
const currentUserId = '6184bd15b3f9ad1e34e0d7ea'

Chat.aggregate([
  // 过滤出当前用户作为发送方或接收方的所有消息
  {
    $match: {
      $or: [
        { sender: currentUserId },
        { reciever: currentUserId }
      ]
    }
  },
  // 生成双向会话唯一标识:不管收发顺序,两个用户ID组合后生成的字符串唯一
  {
    $addFields: {
      sessionKey: {
        $concat: [
          { $min: ['$sender', '$reciever'] },
          '-',
          { $max: ['$sender', '$reciever'] }
        ]
      }
    }
  },
  // 按消息创建时间倒序,最新的消息排在最前
  {
    $sort: { createdAt: -1 }
    // 如果没有开启timestamps,用_id倒序也可以,ObjectId自带时间戳属性
    // $sort: { _id: -1 }
  },
  // 按会话标识分组,每组取第一条就是最新消息
  {
    $group: {
      _id: '$sessionKey',
      latestMsg: { $first: '$$ROOT' }
    }
  },
  // 把分组后的最新消息提为根文档,返回结构和普通查询一致
  {
    $replaceRoot: { newRoot: '$latestMsg' }
  }
]).then(res => {
  // res即为每个会话最新一条消息的列表
  console.log(res)
}).catch(err => {
  console.error('查询失败:', err)
})

注意事项

  • 如果你需要查询全量所有用户的会话最新消息,删除第一个$match阶段即可
  • 注意你给出的集合字段拼写为reciever,如果实际字段是标准拼写receiver需要同步修改代码里的字段名
  • 生产环境建议给sender和reciever字段加联合索引,提升查询性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:36:03