mongoose设置严格为false会禁用validation

我有以下架构

var Schema = new mongoose.Schema({ type: {required: true, type: String, enum: ["device", "beacon"], index: true}, device: { type: {type: String}, version: {type: String}, model: {type: String} }, name: String, beaconId: {required: false, type: mongoose.Schema.Types.ObjectId}, lastMeasuredTimestamp: {type: Number, index: true}, lastMeasuredPosition: {type: [Number], index: "2dsphere"}, lastMeasuredFloor: {type: Number, index: true} }, {strict: false}); 

请注意,我已严格设置为false。 这是因为将未在模式中定义的自定义属性添加到文档是有效的。

接下来,我执行以下查询DB.Document.update({_id: "SOME_ID_HERE"}, {$set: {type: "bull"}}, {runValidators: true})

这将根据Mongoose模式将属性“types”更改为无效的值。 我使用runValidators选项来确保运行模式validation。

然而,这个查询的最终结果是“types”更改为“公牛”,没有validation运行。 当我严格设置为真,但validation运行,并(错误)(正确)显示。

为什么严格影响是否validation运行? 当我看这个描述http://mongoosejs.com/docs/guide.html#strict它只提到了严格的限制,添加架构中没有定义的属性(我不希望这个特定的模式)。

安装信息:

  • Ubuntu 14.04 LTS
  • MongoDB 3.0.8
  • mongoose4.2.3
  • NodeJS 0.10.25
  • NPM 1.3.10

经过一番尝试,我find了一个可行的解决scheme。 如果将来的Mongoose用户遇到同样的问题,我会在这里发布。

诀窍是在Mongoose文档上使用save方法。 由于某些原因,这个确实运行了validation器,同时也允许使用strict选项。

所以更新文档的基本过程如下所示:

  • 使用Model.findOnefind文档
  • 将更新应用于文档(例如,通过合并现有文档中的更新值)
  • 通话save在文件上。

在代码中:

  // Find the document you want to update Model.findOne({name: "Me"}, function(error, document) { if(document) { // Merge the document with the updates values merge(document, newValues); document.save(function(saveError) { // Whatever you want to do after the update }); } else { // Mongoose error or document not found.... } }); // Merges to objects and writes the result to the destination object. function merge(destination, source) { for(var key in source) { var to = destination[key]; var from = source[key]; if(typeof(to) == "object" && typeof(from) == "object") deepMerge(to, from); else if(destination[key] == undefined && destination.set) destination.set(key, from); else destination[key] = from; } }