如果字段设置为null,mongoose如何恢复默认值

3

我将使用mongoose与nodeJS。考虑以下模式:

var PersonSchema = new mongoose.Schema({
    "name": {type: String, default: "Human"},
    "age": {type: Number, defualt:20}
});
mongoose.model('Person', PersonSchema);

var order = new Order({
    name:null
});

这将创建一个新的Person文档,将姓名设置为null。

{
    name:null,
    age: 20
}

有没有办法检查正在创建/更新的属性是否为 null,如果是 null,则将其设置回默认值。以下声明:
var order = new Order();
order.name = null;
order.save(cb);

应该创建一个新的Person文档,并将名称设置为默认值。
{
    name:"Human",
    age: 20
}

如何使用NodeJs和mongoose实现这个功能。
3个回答

4
这个问题有几种解决方法:

预保存/预验证勾子

Mongoose中间件钩子

中间件(也称为pre和post hooks)是在异步函数执行期间传递控制的函数。

PersonSchema.pre('save', function(next) {
    if (this.name === null) {
        this.name = 'Human';
    }

    next();
});

枚举

Mongoose验证Mongoose枚举

字符串有枚举、匹配、最大长度和最小长度验证器。

var PersonSchema = new mongoose.Schema({
    "name": {type: String, default: "Human", enum: ['Human', 'NONE-Human']},
    "age": {type: Number, defualt:20}
});

更新1

如果我有20个字段想要检查它们是否设置为null,我是否需要重复使用this.field = default?

我想你需要这样做。

枚举类型中的NONE-Human是什么意思?我在网上找不到相关文档。

这只是一个ENUM的示例。使用enum时,您只能选择枚举中指定的值,即“Name”只能具有“Human”或“NONE-Human”的值。


谢谢!我有两个快速的跟进问题。
  1. 如果我有20个字段,我想检查它们是否设置为null,我是否必须为它们所有重复使用this.field = default?
  2. 枚举中的NONE-Human是什么意思?我在网上找不到相关文档。
- Neil Sanghrajka
@NeilSanghrajka,我已经更新了我的回答并回答了你的问题。=) - Tim
@NeilSanghrajka 如果你觉得我的帮助有用的话,能否选择我的答案作为被采纳的答案呢?谢谢 - Tim
不错。但是请看@Ralph的https://dev59.com/a5jga4cB1Zd3GeqPObzr#42633419,他很好地概括了它。 - daydreamer

4
稍微晚了些回答这个问题,但更通用的方法是在预钩子中不再硬编码字段。相反,让我们使用模式本身来遍历字段并检查那些具有默认值且明确设置为null的字段。在这种情况下,我们将其设置为默认值。
PersonSchema.pre('save', function(next) {
  const self = this;
  Object.keys(this.schema.paths).forEach(function(key) {
    if(self.schema.paths[key].options.default && self[key] === null) {
      self[key] = self.schema.paths[key].options.default;
    }
  });
  next();
});

警告似乎是TypeScript不喜欢“self[key]”这种表示法。只需使用“self.set(key, value)”和“self.get(key)”来分别设置和获取值即可。 - daydreamer

2
一个更晚的答案。我正在寻找一个更简单的解决方案,偶然看到了这个问题。想分享一下我最终采取的方法。"最初的回答"
db.Person.create({
   name: usersName || "Human",
   age: usersAge,
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接