猫鼬:如果值是“”,则不更新,但否则更新

时间:2020-02-03 13:29:11

标签: mongodb mongoose

在更新一条记录时,如果值是“”,则现有值将被覆盖,我不希望这样...

      const company = "myCo"
      const name = "someName"
      const description = '';
      const image = ''
      const updated = await assetClasses
        .updateOne(
          { company, name },
          {
            $set: {
              description,
              image,
            },
          }, 
          {
            upsert: true,
          }
        )
        .exec();

数据看起来像

_id:5e38002a56fa5e54f1fe10de
indistructable:false
company:"myCo"
description:"dont overwrite me"
image:"myimage.png"
name:"someName"
supply:10000
createdAt:2020-02-03T11:12:42.371+00:00
updatedAt:2020-02-03T13:21:35.924+00:00
__v:0

1 个答案:

答案 0 :(得分:1)

我已经开发了一些变体,假设您只想避免使用空字符串,所以这全都与字符串有关。

变体1 (接受非空字符串;如果为空-从db获取现有值):

const setIfNotEmptyString = (value, defaultValue) => ({
  $switch: {
    branches: [{
      case: {
        $not: {
          $eq: [value, '']
        }
      },
      then: value
    }],
    default: defaultValue
  }
});

await assetClasses.updateOne({
  company, name
}, [{
  $set: {
    description: setIfNotEmptyString(description, "$description"),
    image: setIfNotEmptyString(image, "$image")
  }
}], { upsert: true }).exec();

变体2 (与1相同,更简单):

const setIfNotEmptyString = (value, defaultValue) => ({ $cond: [{ $not: {$eq: [value, '']} }, value, defaultValue] });

await assetClasses.updateOne({
  company, name
}, [{
  $set: {
    description: setIfNotEmptyString(description, "$description"),
    image: setIfNotEmptyString(image, "$image")
  }
}], { upsert: true }).exec();

变体3 (编辑模型,不允许存储空字符串): 例如,如果您的猫鼬模型如下所示:

{
    ...
    description: String,
    image: String
}

然后,您只需添加其他规则即可:

{   ...
    description: {
        type: String,
        minlength: 1
    },
    image: {
        type: String,
        minlength: 1
    }
}

在更新查询中,您需要传递选项runValidators

{runValidators:true}

您还可以将变体1/2与3组合在一起。

来源:

  1. MongoDB use of $set operator + examples
  2. Mongoose validators (minLength) + runValidators option