
本文旨在指导开发者如何在 Mongoose 中实现用户添加好友的功能,重点讨论了如何处理好友请求、更新用户的好友列表,以及避免潜在的数据一致性问题。文章将探讨使用 FriendRequest 模型来管理好友关系,并分析直接在 User 模型中维护好友列表的优缺点,同时提供相应的代码示例和注意事项。
处理好友请求
首先,我们需要一个机制来处理好友请求。一个常见的做法是创建一个 FriendRequest 模型,用于存储好友请求的发送者、接收者和状态。
FriendRequest Schema:
const mongoose = require('mongoose');const friendRequestSchema = new mongoose.Schema({ sender: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true, }, receiver: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true, }, status: { type: String, enum: ["pending", "accepted", "rejected"], default: "pending", }, createdAt: { type: Date, default: Date.now, },});const FriendRequest = mongoose.model('FriendRequest', friendRequestSchema);module.exports = FriendRequest;
发送好友请求的路由:
在发送好友请求的路由中,我们需要确保只有经过身份验证的用户才能发送请求。 建议使用中间件来验证用户身份,并从已验证的用户信息中获取发送者的 ID,而不是从前端传递。这样可以避免潜在的安全风险,例如用户篡改请求中的发送者 ID。
router.post("/requests", (req, res) => { const { receiver } = req.body; FriendRequest.create({ sender: req.user._id, // 从经过身份验证的用户获取 receiver, }) .then(() => { res.status(204).send(); }) .catch((error) => { console.error(error); // 记录错误信息 res.status(500).send("Error sending friend request"); });});
处理好友请求的接受/拒绝
当用户接受或拒绝好友请求时,我们需要更新 FriendRequest 模型的 status 字段。
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(); // TODO: 更新 User 模型的好友列表 (见下文) res.redirect("/requests"); } catch (error) { console.error(error); res.status(500).send("Error accepting friend request"); }});router.post("/requests/:id/reject", 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 = "rejected"; await request.save(); res.redirect("/requests"); } catch (error) { console.error(error); res.status(500).send("Error rejecting friend request"); }});
更新 User 模型的好友列表
现在,让我们讨论如何更新 User 模型的好友列表。 有两种主要方法:
直接在 User 模型中维护好友列表: 在 User 模型中添加一个 friends 数组,存储好友的 ID。通过查询 FriendRequest 模型获取好友列表: 不在 User 模型中存储好友列表,而是通过查询 FriendRequest 模型,查找所有 status 为 “accepted” 的好友请求,来动态获取好友列表。
方法 1:直接在 User 模型中维护好友列表
// User Schemaconst userSchema = new mongoose.Schema({ firstname: String, lastname: String, username: { type: String, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, "is invalid"], index: true, }, password: String, createdAt: { type: Date, default: Date.now }, profilePictureURL: String, friends: [ { type: mongoose.Schema.Types.ObjectId, ref: "User", }, ],});const User = mongoose.model('User', userSchema);module.exports = User;// 在接受好友请求的路由中更新 User 模型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 senderId = request.sender; const receiverId = request.receiver; // 更新发送者的好友列表 const sender = await User.findById(senderId); if (!sender) { return res.status(404).send("Sender not found"); } sender.friends.push(receiverId); await sender.save(); // 更新接收者的好友列表 const receiver = await User.findById(receiverId); if (!receiver) { return res.status(404).send("Receiver not found"); } receiver.friends.push(senderId); await receiver.save(); res.redirect("/requests"); } catch (error) { console.error(error); res.status(500).send("Error accepting friend request"); }});
注意事项:
事务: 同时更新两个 User 模型的 friends 数组是一个潜在的数据一致性问题。 如果在更新其中一个模型时发生错误,可能会导致数据不一致。 为了解决这个问题,应该使用 Mongoose 的事务功能。错误处理: 在更新 User 模型之前,应该检查用户是否存在。
方法 2:通过查询 FriendRequest 模型获取好友列表
这种方法避免了在 User 模型中维护冗余数据。 要获取用户的好友列表,只需查询 FriendRequest 模型,查找所有 sender 或 receiver 为该用户 ID,并且 status 为 “accepted” 的记录。
// 获取好友列表的路由router.get("/users/:userId/friends", async (req, res) => { try { const userId = req.params.userId; const friendRequests = await FriendRequest.find({ $or: [{ sender: userId }, { receiver: userId }], status: "accepted", }).populate('sender receiver'); // populate 用于获取用户详细信息 const friends = friendRequests.map(request => { if (request.sender._id.toString() === userId) { return request.receiver; } else { return request.sender; } }); res.json(friends); } catch (error) { console.error(error); res.status(500).send("Error fetching friends"); }});
优点:
避免了数据冗余和潜在的数据一致性问题。简化了数据更新的逻辑。
缺点:
每次获取好友列表都需要执行数据库查询,可能会影响性能。
总结
选择哪种方法取决于具体的应用场景。 如果性能是关键因素,并且好友列表不经常更新,那么在 User 模型中维护好友列表可能更合适。 但是,如果数据一致性是首要考虑因素,或者好友列表经常更新,那么通过查询 FriendRequest 模型获取好友列表可能更合适。
无论选择哪种方法,都应该注意潜在的数据一致性问题,并使用事务来确保数据完整性。 此外,应该对代码进行充分的错误处理,以防止意外情况发生。
以上就是在 Mongoose 中实现用户添加好友功能:最佳实践指南的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1524218.html
微信扫一扫
支付宝扫一扫