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

使用 Mongoose 更新用户的好友列表:最佳实践指南

心靈之曲
发布: 2025-09-28 17:09:14
原创
328人浏览过

使用 mongoose 更新用户的好友列表:最佳实践指南

本文旨在指导开发者如何在使用 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");
    });
});
登录后复制

维护好友列表的策略:直接 vs. 间接

有两种主要策略来维护好友列表:

  1. 直接方法: 在 User Schema 中维护一个 friends 数组,存储好友的 ObjectId。
  2. 间接方法: 依赖 FriendRequest Schema,通过查询 status 为 "accepted" 的请求来获取好友列表。

间接方法:查询 FriendRequest Schema

如果采用间接方法,你无需在 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 数组

如果选择在 User Schema 中维护 friends 数组,需要在接受好友请求时更新双方用户的 friends 数组。

堆友
堆友

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

堆友 306
查看详情 堆友
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");
    }
});
登录后复制

代码解释:

  1. mongoose.startSession(): 启动一个新的 Mongoose 会话,用于事务管理。
  2. session.startTransaction(): 开始事务。
  3. .session(session): 将会话传递给所有 Mongoose 操作 (例如 findById, save)。
  4. session.commitTransaction(): 提交事务,将所有更改保存到数据库。
  5. session.abortTransaction(): 如果出现错误,中止事务,回滚所有更改。
  6. session.endSession(): 结束会话。

总结

管理用户好友关系需要仔细考虑安全性、数据一致性和性能。 使用经过身份验证的用户 ID,选择适合你的应用需求的维护策略(直接或间接),并始终使用事务来保证数据一致性,这些都是至关重要的。 通过遵循这些最佳实践,你可以构建一个健壮且可靠的社交应用。

以上就是使用 Mongoose 更新用户的好友列表:最佳实践指南的详细内容,更多请关注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号