如何在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里遍历一便,找是否有该用户,然后也获得了在线数据,这种方法感觉对数据库的操作量太大了,会不会影响速度神马的。
本人小白,还请前辈贡献一点经验,实再是乱了头绪了,还有,如果下线的话怎么处理
当然可以!你提到的需求是关于如何在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模型来管理用户的在线状态。以下是一种更为优化的方案,结合了上述两种方法的优点:
-
定义Online Model:为每个用户维护一个独立的在线状态文档,这样可以在用户上线和下线时高效地更新状态。
-
减少重复数据:通过设计合理的数据结构,避免不必要的重复存储。
以下是具体的实现步骤和示例代码:
定义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');
}
});
这种方法通过维护每个用户的独立在线状态文档,可以有效地进行上线和下线操作,并且查询在线状态也非常高效。