【问题标题】:Don't overwrite value in mongo if new value is null如果新值为 null,则不要覆盖 mongo 中的值
【发布时间】:2019-12-12 23:00:23
【问题描述】:

当使用节点做 mongoose 时,我可以使用 .. 更新 mongo 中的文档。

      const account = await userModel
        .findOneAndUpdate(
          { 'shared.email': email },
          {
          $set: {
            'shared.username': req.body.username,
             ...
            'shared.country': req.body.country,
            'shared.dob': dob,
            },
          },
          {
            new: true,
          }
        )
        .exec();

req.body.usernamenull''shared.username 已经在mongo 是James 有没有办法保留用户名James 而不是用null'' 覆盖它?

userModel 架构是...

const userSchema: Schema = new Schema(
  {
    email: {
      confirmationCode: { type: String, unique: true, index: true },
      confirmationSentAt: { type: Date },
      confirmed: { type: Boolean, default: false },
    },
    password: {
      hash: { type: String },
      resetCode: { type: String, unique: true, index: true },
      sentAt: { type: Date },
    },
    shared: {
      avatarId: { type: String },
      bio: { type: String },
      country: { type: String },
      dob: { type: Date },
      email: { type: String, required: true, unique: true, index: true },
      fullName: { type: String },
      gender: { type: String },
      language: { type: String, default: 'en' },
      location: { type: String },
      loggedIn: { type: Boolean, default: true },
      username: { type: String, unique: true, index: true },
      warningMessage: { type: String, default: 'verify' },
      webSite: { type: String },
    },
  },
  {
    timestamps: true,
  }
);

【问题讨论】:

  • 这能回答你的问题吗? stackoverflow.com/a/59094214/11717458
  • 不,这不是关于子文档,而是关于当新值为 null 时如何保留原始值,并且它特定于 Mongoose 和 Node.js,例如它与 mongo 和 java 无关
  • 你能提供样品请求正文吗?
  • 正如我所说的req.body.usernamenull''
  • 您可以在问题中添加用户模型代码吗?

标签: node.js mongoose


【解决方案1】:

您可以排除具有虚假值的字段,并将此过滤后的对象发送到更新查询。

  const { email, username, country } = req.body;

  let filteredBody = {};

  if (username) {
    filteredBody["shared.username"] = username;
  }

  if (country) {
    filteredBody["shared.country"] = country;
  }

  console.log(filteredBody);

  const account = await userModel.findOneAndUpdate(
    { "shared.email": email },
    filteredBody,
    {
      new: true
    }
  );

测试:

假设我们的集合中有这个现有用户。

{
    "_id": "5df24ed1ec018d37785c23bd",
    "shared": {
        "email": "user1@gmail.com",
        "username": "user1",
        "country": "USA"
    }
}

当我们发送这样的请求正文时:

{
        "email": "user1@gmail.com",
        "username": "",
        "country": "England"
}

用户名字段不会更新,但国家会像这样更新:

{
    "shared": {
        "email": "user1@gmail.com",
        "username": "user1",
        "country": "England"
    },
    "_id": "5df24ed1ec018d37785c23bd"
}

【讨论】:

    【解决方案2】:
    //Pass all you need to update in all cases to setData. And append username if available
    const setData = {
            'shared.country': req.body.country,
            'shared.dob': dob,
            },
    }
    
    if(req.body.username){
      setData['shared.username'] = req.body.username;
    }
    
    
    const account = await userModel
        .findOneAndUpdate(
          { 'shared.email': email },
          {
          $set: setData,
          {
            new: true,
          }
        )
        .exec();
    

    【讨论】:

      【解决方案3】:

      即使您为字段指定了类型,Mongoose 的预期行为也是接受“null”。

      所以,如果你想拒绝一个“空”值,你有两个选择:

      选项 1. 在您的架构中,将“required: true”添加到该字段。它也适用于“未定义”值和空字符串。

      选项 2。在您的函数中,添加一个 if 语句,该语句将在更新之前检查值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-04
        • 1970-01-01
        • 1970-01-01
        • 2020-08-18
        • 2018-11-02
        • 1970-01-01
        • 2011-09-15
        • 2020-06-06
        相关资源
        最近更新 更多