mongoose - 有可选的附加隐式字段

时间:2015-08-06 10:21:54

标签: node.js mongodb mongoose

我有一个包含字段的架构,我可以在其中存储任何内容:new Schema({settings : {}})

我有一个数据库 我想保持这种添加数据的能力而不添加新字段,但是如果某些字段不存在则会有一些默认值。

我可以做以下事情:

new Schema({
   settings : {
       key : { type : String, default: "abc" }
       // I want to be able to add data that contains more than just "key"
   }
});

我只是想确保在从此架构请求数据时,我仍然会获得所有数据,而不仅仅是明确定义的键?

它似乎有效,但我想确保我仍然可以:

  • 阅读所有数据

  • 写任意数据(即未必在架构中定义)

是否有关于mongo / mongoose的规则会阻止我做这两件事之一(我对写作部分非常不确定)?如果有这样一个"功能",怎么办呢?

注意:我看到了this question。如果我错了,请纠正我,但这些字段不是隐含的(比如第一种情况下{}),并且必须定义(它实际上是相反的问题)。

编辑:我现在也看到this question解决了我的问题(即使接受的解决方案听起来更像是对我的解决方法)。但在我的情况下,我已经存储了数据(1 - 禁用严格)意味着编写大量验证代码是安全的(因为很多密钥,这是应用程序的最大集合),以及(2 - 混合模式)需要迁移这个特定子元素的数据......简而言之:我仍然欢迎解决我的特定问题。

2 个答案:

答案 0 :(得分:1)

我认为您需要在此构建自己的自定义验证,而不是依赖于defauly模式类型验证方法。幸运的是,mongoose有这样的设施:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');

var testSchema = new Schema({
  settings: {}
});

var Test = mongoose.model( 'Test', testSchema, "test" );

testSchema.path('settings').validate(function(value) {
  return Object.keys(value).indexOf("key") != -1;
},'Error "settings" must contain "key" as "settings.key"');


//var test = new Test({ settings: { "key": "something" } });
var test = new Test({ settings: { } });

test.save(function(err) {
  try {
    if (err) throw err;
    console.log(test);
  } catch (e) {
    console.log(e);
  }
});

所以基本上,我在那里为模式中的“设置”路径设置了验证功能,以便用它自己的对象查找“key”的存在。如果该“密钥”不存在,则会在错误中报告异常。

与任何此类错误一样,当您err对象时,它将在.save()对象中返回,从而阻止写入。然后可以根据需要处理错误,并使用已定义的消息进行处理。

这是一个自包含的“测试”,您可以交替取消注释对象的有效数据,并成功保存该对象而不会报告错误。

或者,您可以执行“预存”以填写一些默认数据:

testSchema.pre("save",function(next) {
  this.settings = (this.settings) ? this.settings : {};
  if (Object.keys(this.settings).indexOf("key") == -1)
    this.setting.key = "abc";
  next();
});

如果尚未填写默认值,则填写默认值。

答案 1 :(得分:0)

尝试这样使用

new Schema({
    settings : {}
});

var modelObj = new myModel();
modelObj.settings.key = "keyval";
modelObj.settings.key1 = "keyval";
modelObj.settings.key2 = "keyval";
modelObj.settings.key3 = "keyval";
modelObj.save(function(err){
    //handle
});