如何使Mongoose不将空数组或对象字段插入到文档中

时间:2017-05-12 09:51:23

标签: javascript node.js mongodb mongoose

我们假设我们的Mongoose项目中有Node.js架构:

let coolSchema = new mongoose.Schema({
  field_1 : Number,
  field_2 : String,
  field_3 : [ String ],
});

让我们有一个相应的对象:

var data = {
  field_1 : 123,
  field_2 : 'blah',
  field_3 : ['aa', 'bb'],
};

现在要将这些数据保存到MongoDB,我们可以使用以下代码:

let Model = require('mongoose').model('CoolModel', coolSchema);
(new Model(data)).save();

好的,虽然它很酷。

但是如果data不包含field_3(数组字段,并且对象字段也是如此),Mongoose无论如何都会将此字段添加到具有空值的正在创建的文档中

如果Mongoose对象中没有包含此字段,我们可以告诉data不要创建此字段吗?

3 个答案:

答案 0 :(得分:1)

对这个问题本身并不是特别的回答,而是对此事的一些思考。

目前还不清楚你在这里想要实现的目标。您定义了一个应该包含字符串列表的模式。 Mongoose正确地这样做,以便模式中保存的数据与模式的定义一致。

在这种情况下,列表更多是架构的结构部分。如果您有不同的行为,则必须在代码中处理特殊情况,以防列表不存在。现在,您可以放心地假设您的模式总是返回一个列表,因此获取一些数据总是允许您这样做:

coolData.field_3.forEach(function(x) {
   do_cool_things(x)
})

你要问的是让架构允许从mongodb返回不一致的数据...换句话说,你必须这样做以防止访问未定义的属性:

if (coolData.field_3) {
   coolData.field_3.forEach(function(x) {
      do_cool_things(x)
   })
}

另外,我试图优化对象/数据库的大小,你可以填写错误报告,这样mongoose在保存对象时不会定义空值,并在缺少字段时使用默认值自动填充它们MongoDB的。 (我可能错了,但你确实检查过mongodb中的数据是否包含空值,或者你只是查看来自mongoose的数据?)

答案 1 :(得分:0)

这是因为您没有在架构定义中标记所需的字段。 这样做:

let coolSchema = new mongoose.Schema({
  field_1 : { type: Number, required: true },
  field_2 : { type: String, required: true },
  field_3 : { type: [ String ], required: true },
});

答案 2 :(得分:0)

接受的答案很好。但是如果您不想使用预挂钩,那么您可以将 default: undefined 添加到数组字段中。例如:

var schema = new Schema({
  myArr: { type: [String], default: undefined }
});

有关详细说明,请参阅 this comment