如何在Nodejs中使用mongoose分布model,朋友,在线,能最快的查询和更新在线列表

如何在Nodejs中使用mongoose分布model,朋友,在线,能最快的查询和更新在线列表

我有两种想法: 一、在朋友里加个friends model里,有主人_id,朋友_id,online:boolean,每当我上线时,我更新所有朋友_id为我的_id的文档online为true,然后在别人上线时,查找主人_id与其对应的所有文档,并可获得是否在线内容,但是这里面就有了大量的重复,两个人之间为朋友关系至少存在两条数据,感觉这种方法有点冗余。 二、创建一个online model,只要上线就添加到online里,friends里,有user_1_id,user_2_id,用user_1_id查找一遍符合我的_id的文档,再用user_2_id查找一遍符合我的_id的文档,两者加起来是我总共的朋友,再用for in语句使每个在朋友在online里遍历一便,找是否有该用户,然后也获得了在线数据,这种方法感觉对数据库的操作量太大了,会不会影响速度神马的。

本人小白,还请前辈贡献一点经验,实再是乱了头绪了,还有,如果下线的话怎么处理


4 回复

当然可以!你提到的需求是关于如何在Node.js中使用Mongoose来高效地管理在线朋友列表。这里提供一种简洁且高效的方案。

方案概述

我们可以使用一个单独的OnlineUser模型来记录当前在线的用户。这个模型包含用户ID和其他相关信息。通过这种方式,我们可以在每次用户上线或下线时快速更新状态,同时也能快速查询在线用户列表。

示例代码

首先,我们需要安装Mongoose库(如果还没有安装的话):

npm install mongoose

接下来,定义OnlineUser模型:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// 定义OnlineUser模型
const OnlineUserSchema = new Schema({
    userId: { type: String, required: true, unique: true },
    lastSeen: { type: Date, default: Date.now }
});

const OnlineUser = mongoose.model('OnlineUser', OnlineUserSchema);

上线操作

当用户上线时,更新或插入他们的在线状态:

async function userOnline(userId) {
    try {
        await OnlineUser.findOneAndUpdate(
            { userId: userId }, // 查找条件
            { $set: { lastSeen: Date.now() } }, // 更新内容
            { upsert: true } // 如果不存在则插入
        );
    } catch (error) {
        console.error('Error updating online status:', error);
    }
}

查询在线用户

为了查询某个用户的在线状态,可以使用以下方法:

async function isUserOnline(userId) {
    const user = await OnlineUser.findOne({ userId: userId });
    return !!user; // 如果找到用户,则返回true,否则返回false
}

下线操作

当用户下线时,删除其在线状态记录:

async function userOffline(userId) {
    try {
        await OnlineUser.deleteOne({ userId: userId });
    } catch (error) {
        console.error('Error removing offline status:', error);
    }
}

总结

这种方案利用了Mongoose的findOneAndUpdate方法来高效地更新或插入在线状态记录。通过这种方式,我们避免了重复的数据存储,并且能够快速地查询和更新用户的在线状态。这种方式在大规模应用中表现良好,因为只需要一次查询即可完成状态更新,而不需要进行复杂的多表查询。


pub/sub 事件式的处理

恩,现在正在学习redis,感觉刚接触,很新奇的样子

为了实现快速查询和更新在线列表,可以考虑使用Mongoose模型来管理用户的在线状态。以下是一种更为优化的方案,结合了上述两种方法的优点:

  1. 定义Online Model:为每个用户维护一个独立的在线状态文档,这样可以在用户上线和下线时高效地更新状态。

  2. 减少重复数据:通过设计合理的数据结构,避免不必要的重复存储。

以下是具体的实现步骤和示例代码:

定义Online Model

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const OnlineSchema = new Schema({
    userId: { type: String, required: true },
    online: { type: Boolean, default: false }
});

const OnlineModel = mongoose.model('Online', OnlineSchema);

用户上线逻辑

async function userOnline(userId) {
    try {
        await OnlineModel.findOneAndUpdate(
            { userId },
            { $set: { online: true } },
            { upsert: true }
        );
    } catch (err) {
        console.error(err);
    }
}

用户下线逻辑

async function userOffline(userId) {
    try {
        await OnlineModel.findOneAndUpdate(
            { userId },
            { $set: { online: false } }
        );
    } catch (err) {
        console.error(err);
    }
}

查询在线用户

async function getOnlineUsers() {
    try {
        const onlineUsers = await OnlineModel.find({ online: true });
        return onlineUsers.map(user => user.userId);
    } catch (err) {
        console.error(err);
    }
}

示例使用

// 假设有一个用户上线
userOnline('userId123');

// 假设需要检查某个用户是否在线
getOnlineUsers().then(onlineUsers => {
    if (onlineUsers.includes('userId123')) {
        console.log('User is online');
    } else {
        console.log('User is offline');
    }
});

这种方法通过维护每个用户的独立在线状态文档,可以有效地进行上线和下线操作,并且查询在线状态也非常高效。

回到顶部