如果新值为null,请勿覆盖mongo中的值

时间:2019-12-12 14:19:13

标签: node.js mongoose

当用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,
  }
);

3 个答案:

答案 0 :(得分: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"
}

答案 1 :(得分:0)

//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();

答案 2 :(得分:0)

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

因此,如果要拒绝“空”值,则有两个选择:

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

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