
本文旨在指导开发者如何在使用 Mongoose 构建社交应用时,正确地更新用户的好友列表。文章将探讨如何安全有效地处理好友请求的接受流程,并讨论维护用户好友列表的不同策略,包括直接在 User Schema 中维护以及通过查询 FriendRequest Schema 间接获取。同时,本文将强调数据一致性的重要性,并建议使用事务来确保数据库操作的原子性。
在构建社交应用时,管理用户之间的好友关系是一个常见的需求。本文将深入探讨如何使用 Mongoose 在用户接受好友请求后,更新双方用户的好友列表。我们将讨论安全性、数据一致性以及不同的实现策略。
首先,务必确保好友请求的发送者身份已通过验证。不要依赖客户端发送的 sender ID,因为这可能被篡改。使用服务器端已经验证过的用户 ID,通常可以通过中间件获取。
router.post("/requests", (req, res) => {
const { receiver } = req.body;
FriendRequest.create({
sender: req.user._id, // 从经过身份验证的用户获取 sender ID
receiver,
})
.then(() => {
res.status(204).send();
})
.catch((error) => {
res.status(500).send("Error sending friend request");
});
});有两种主要策略来维护好友列表:
如果采用间接方法,你无需在 User Schema 中维护 friends 数组。你可以通过查询 FriendRequest 集合来动态获取好友列表。
FriendRequest.find({
$or: [
{ sender: req.user._id, status: "accepted" },
{ receiver: req.user._id, status: "accepted" },
],
})
.then((listOfFriends) => {
console.log(listOfFriends);
})
.catch((e) => {
// 处理错误
});这种方法的优点是避免了在多个地方更新数据,降低了数据不一致的风险。
如果选择在 User Schema 中维护 friends 数组,需要在接受好友请求时更新双方用户的 friends 数组。
router.post("/requests/:id/accept", async (req, res) => {
try {
const request = await FriendRequest.findById(req.params.id);
if (!request) {
return res.status(404).send("Friend request not found");
}
request.status = "accepted";
await request.save();
const currentUser = await User.findById(request.receiver);
const friendUser = await User.findById(request.sender);
if (!currentUser || !friendUser) {
return res.status(404).send("User not found");
}
currentUser.friends.push(request.sender);
friendUser.friends.push(request.receiver);
await currentUser.save();
await friendUser.save();
res.redirect("/requests");
} catch (error) {
console.error(error);
res.status(500).send("Error accepting friend request");
}
});重要注意事项:使用事务
当同时更新多个集合(例如 FriendRequest 和 User)时,必须使用事务来保证数据的一致性。如果服务器在更新过程中崩溃,事务可以回滚所有更改,防止数据损坏。
以下是如何使用 Mongoose 事务的示例:
const mongoose = require('mongoose');
router.post("/requests/:id/accept", async (req, res) => {
const session = await mongoose.startSession();
session.startTransaction();
try {
const request = await FriendRequest.findById(req.params.id).session(session);
if (!request) {
await session.abortTransaction();
session.endSession();
return res.status(404).send("Friend request not found");
}
request.status = "accepted";
await request.save({ session });
const currentUser = await User.findById(request.receiver).session(session);
const friendUser = await User.findById(request.sender).session(session);
if (!currentUser || !friendUser) {
await session.abortTransaction();
session.endSession();
return res.status(404).send("User not found");
}
currentUser.friends.push(request.sender);
friendUser.friends.push(request.receiver);
await currentUser.save({ session });
await friendUser.save({ session });
await session.commitTransaction();
session.endSession();
res.redirect("/requests");
} catch (error) {
await session.abortTransaction();
session.endSession();
console.error(error);
res.status(500).send("Error accepting friend request");
}
});代码解释:
总结
管理用户好友关系需要仔细考虑安全性、数据一致性和性能。 使用经过身份验证的用户 ID,选择适合你的应用需求的维护策略(直接或间接),并始终使用事务来保证数据一致性,这些都是至关重要的。 通过遵循这些最佳实践,你可以构建一个健壮且可靠的社交应用。
以上就是使用 Mongoose 更新用户的好友列表:最佳实践指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号