如何在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
相关产品推荐
相关产品推荐

