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

MongoDB中如何统计聊天消息数组内未读消息的数量?

如何统计聊天服务器中未读消息数量?

问题描述

我正在搭建一个聊天服务器,需要获取标记为seen: false的消息数量。

数据Schema如下:

const ChatSchema = mongoose.Schema({
    chatId: { type: String, required: true, unique: true },
    messages: [
        {
            message: { type: String, required: true },
            sendBy: { type: String, required: true },
            sendTo: { type: String, required: true },
            seen: { type: Boolean, default: false },
            date: { type: Date, default: Date.now()}
        },
    ],
})

我尝试了以下代码,但它总是返回1:

const unSeenCount=await Chat.find({ chatId: chatId }, 
            { messages : { $elemMatch : { seen : false } } })
        
console.log(`unseen count is ${unSeenCount.length}`);

我认为这段代码仅获取了符合{ chatId: chatId }条件的文档,而非未读消息的实际数量。

解决方案

你的判断是对的——find()返回的是匹配chatId的完整文档(每个chatId对应唯一文档),所以unSeenCount.length只会是1,和未读消息的实际数量无关。

下面提供两种正确的统计方式:

方法1:数据库层面聚合计算(推荐大数据量场景)

用MongoDB的聚合框架直接在数据库中筛选并统计未读消息数量,减少数据传输:

const result = await Chat.aggregate([
    // 先匹配目标聊天文档
    { $match: { chatId: chatId } },
    // 投影计算未读消息数量
    {
        $project: {
            unreadCount: {
                $size: {
                    $filter: {
                        input: "$messages",
                        cond: { $eq: ["$$this.seen", false] }
                    }
                }
            }
        }
    }
]);

// 处理查询结果,没有匹配文档则返回0
const unSeenCount = result.length ? result[0].unreadCount : 0;
console.log(`unseen count is ${unSeenCount}`);

方法2:内存中筛选统计(适合小数据量场景)

如果已经获取了聊天文档,直接在应用层筛选未读消息:

const chatDoc = await Chat.findOne({ chatId: chatId });
if (!chatDoc) {
    console.log("unseen count is 0");
    return;
}
const unSeenCount = chatDoc.messages.filter(msg => !msg.seen).length;
console.log(`unseen count is ${unSeenCount}`);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:18:17