You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+MongoDB:如何仅存储帖子提及的用户名而非完整用户数据

解决MongoDB Post集合Mentions仅存储提及用户名的问题

问题现状

当前Post集合的mentions字段会存储完整的用户文档(包含密码、token等敏感信息),甚至在未提及用户时会存入数据库所有用户数据,示例如下:

{
    "userId": "62db90256a7a0d1b38ee15b5",
    "media": ["nothing"],
    "mentions": [
        {
            "_id": "62db797c0d2bdc605e6d1810",
            "Name": "Mitul Kheni",
            "email": "test@gmail.com",
            "User_name": "Mitul_kheni",
            "phoneNumber": "1234567890",
            "password": "$2a$08$pb6Nu8MlIX7.L0S8vBP6NOFxjc9rZCXOUFA9.IsMBwkENmap946yO",
            // 其他敏感字段省略
        }
    ]
}

错误原因

  1. 参数接收错误:当前代码试图通过req.body.User_Name获取提及用户,但这不是正确的参数(前端应传递被提及的用户名列表);
  2. 查询逻辑错误:User.find({User_Name: req.body.User_Name})如果req.body.User_Name为空或未传,会匹配所有用户,返回完整用户文档;
  3. Schema定义模糊:mentions字段仅定义为Array,未限制类型,导致可以存入任意数据。

修改方案

1. 修正Post Schema定义

将mentions明确为字符串数组类型,确保仅能存储用户名:

// Post集合Schema
mentions: {
  type: [String], // 明确为字符串数组
  default: [],
},

2. 修改创建帖子的业务代码

调整参数接收、查询逻辑,仅提取并存储被提及的用户名:

exports.createPost = async (req, res) => {
  try {
    const user = await User.findById(req.user._id);
    if (!user) return res.status(401).json({ message: "No user found" });
    
    // 解构请求参数,获取提及的用户名列表(前端需传递mentions字段,值为用户名数组)
    const { media, hashTags, postStatus, mentions: mentionedUserNames = [] } = req.body;

    let mentionUserNames = [];
    if (mentionedUserNames.length > 0) {
      // 查询存在的用户,仅返回User_Name字段
      const foundUsers = await User.find(
        { User_Name: { $in: mentionedUserNames } },
        { User_Name: 1, _id: 0 } // 投影只取用户名
      );
      // 提取用户名数组
      mentionUserNames = foundUsers.map(u => u.User_Name);
      
      // 可选:检查是否有无效用户名
      const invalidNames = mentionedUserNames.filter(name => !mentionUserNames.includes(name));
      if (invalidNames.length > 0) {
        return res.status(404).json({ message: `Invalid user names: ${invalidNames.join(', ')}` });
      }
    }

    const new_post = new Post({
      userId: req.user._id,
      media,
      mentions: mentionUserNames, // 仅存入用户名数组
      hashTags,
      postStatus,
    });
    const post = await new_post.save();
    return res.status(200).send(post);
  } catch (error) {
    return res.status(500).send(error.message);
  }
};

关键修改点说明

  • 参数调整:从req.body.mentions获取前端传递的提及用户名列表,默认空数组;
  • 精准查询:使用$in操作符匹配多个用户名,通过投影仅返回User_Name字段,避免获取敏感数据;
  • 空值处理:当没有提及用户时,直接赋值空数组,不会触发全量用户查询;
  • 可选验证:添加无效用户名检查,返回明确错误信息。

效果验证

修改后,Post集合的mentions字段将仅存储被提及的用户名,示例如下:

{
    "userId": "62db90256a7a0d1b38ee15b5",
    "media": ["nothing"],
    "mentions": ["Mitul_kheni", "another_user"],
    // 其他字段省略
}

内容的提问来源于stack exchange,提问作者Talc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:24:10