首页 > web前端 > js教程 > 正文

在Mongoose中实现好友关系:更新User Schema中的好友数组

碧海醫心
发布: 2025-09-28 16:10:19
原创
578人浏览过

在mongoose中实现好友关系:更新user schema中的好友数组

本文旨在指导开发者如何在Mongoose中实现用户添加好友的功能,重点讲解在接受好友请求后如何正确更新User Schema中的好友数组。同时,文章也会探讨更高效的数据结构设计方案,以及在使用事务时需要注意的关键点,确保数据一致性。

安全地处理好友请求

首先,确保在处理好友请求时,发送者ID来自已验证的用户会话,而不是直接从前端表单获取。从前端获取用户ID存在安全风险,用户可以通过开发者工具篡改表单数据,冒充他人发送请求。

推荐的做法是从服务器端的会话或身份验证中间件中获取当前用户的ID。以下是修改后的前端表单和后端路由示例:

前端表单 (修改后):

<form action="/requests" method="POST">
  <input type="hidden" name="receiver" value="<%= receiverUserId %>" />
  <button type="submit">Send Friend Request</button>
</form>
登录后复制

后端路由 (修改后):

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");
    });
});
登录后复制

在这个修改后的代码中,req.user._id 代表当前已验证用户的ID,你需要根据你使用的身份验证中间件来调整获取用户ID的方式。

更新User Schema中的好友数组

当用户接受好友请求时,需要更新双方的 User Schema,将对方的 _id 添加到各自的 friends 数组中。以下是更新 User Schema 的代码示例:

router.post("/requests/:id/accept", async (req, res) => {
  try {
    const request = await FriendRequest.findById(req.params.id);
    request.status = "accepted";
    await request.save();

    const currentUserId = req.user._id; // 获取当前用户ID
    const currentUser = await User.findById(currentUserId);
    const otherUser = await User.findById(request.sender);

    currentUser.friends.push(request.receiver);
    otherUser.friends.push(currentUserId);

    await currentUser.save();
    await otherUser.save();

    res.redirect("/requests");
  } catch (error) {
    console.error("Error accepting friend request:", error);
    res.status(500).send("Error accepting friend request");
  }
});
登录后复制

注意事项:

堆友
堆友

Alibaba Design打造的设计师全成长周期服务平台,旨在成为设计师的好朋友

堆友 306
查看详情 堆友
  • 在更新 friends 数组之前,请确保 request.receiver 和 currentUserId 都是有效的 ObjectId 类型。
  • 在生产环境中,需要添加错误处理机制,以便在发生错误时能够及时发现并处理。

使用事务保证数据一致性

直接修改两个不同的集合(FriendRequest 和 User)可能导致数据不一致。例如,如果服务器在更新 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);
    request.status = "accepted";
    await request.save({ session });

    const currentUserId = req.user._id; // 获取当前用户ID
    const currentUser = await User.findById(currentUserId).session(session);
    const otherUser = await User.findById(request.sender).session(session);

    currentUser.friends.push(request.receiver);
    otherUser.friends.push(currentUserId);

    await currentUser.save({ session });
    await otherUser.save({ session });

    await session.commitTransaction();
    session.endSession();

    res.redirect("/requests");
  } catch (error) {
    await session.abortTransaction();
    session.endSession();
    console.error("Error accepting friend request:", error);
    res.status(500).send("Error accepting friend request");
  }
});
登录后复制

关键点:

  • mongoose.startSession() 创建一个新的会话。
  • session.startTransaction() 启动一个事务。
  • 在查询和保存文档时,使用 .session(session) 将操作与事务关联。
  • session.commitTransaction() 提交事务,所有操作都将永久保存到数据库。
  • session.abortTransaction() 回滚事务,所有操作都将撤销。
  • session.endSession() 结束会话。

更高效的数据结构设计

虽然在 User Schema 中维护一个 friends 数组是常见的做法,但它可能不是最有效的方法,尤其是在用户拥有大量好友的情况下。

另一种更高效的方法是只维护 FriendRequest 集合,并通过查询来获取好友列表。例如:

FriendRequest.find({
  $or: [
    { sender: req.user._id, status: "accepted" },
    { receiver: req.user._id, status: "accepted" },
  ],
})
  .populate("sender receiver") // 可选:填充用户数据
  .then((friendRequests) => {
    const friends = friendRequests.map((request) => {
      return request.sender._id.equals(req.user._id)
        ? request.receiver
        : request.sender;
    });
    console.log(friends);
  })
  .catch((e) => {
    // handle error
  });
登录后复制

这种方法的优点是不需要在多个集合中维护数据,从而避免了数据不一致的问题。缺点是每次获取好友列表都需要执行查询。

总结

在 Mongoose 中实现好友关系需要仔细考虑数据一致性和性能。使用事务可以确保数据一致性,但会增加代码的复杂性。选择合适的数据结构取决于具体的应用场景和性能要求。在开发过程中,请始终关注安全性,并避免从前端获取敏感数据

以上就是在Mongoose中实现好友关系:更新User Schema中的好友数组的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号