猫鼬:怎么了“
看起来Mongoose在内部正在做一些非常有趣的事情。
1 var Foo = new mongoose.model('Foo', new mongoose.Schema({a: String, b: Number}));
2 var foo = new Foo({a: 'test; b: 42});
3 var obj = {c: 1};
4 foo.goo = obj; // simple object assignment. obj should be
// passed by reference to foo.goo. recall goo
// is not defined in the Foo model schema
5 console.log(foo.goo === obj); // comparison directly after the assignment
// => false, doesn't behave like normal JS object
从本质上讲,任何时候你试图处理模型的模式中定义的aro't a)的Mongoose模型的属性,或者b)定义为相同的类型(数组,obj,..)...模型甚至不会表现得像一个普通的Javascript对象。
将第4行切换到foo._doc.goo = obj
使控制台输出为true
。
编辑 :试图重现怪异
例1 :
// Customer has a property 'name', but no property 'text'
// I do this because I need to transform my data slightly before sending it
// to client.
models.Customer.find({}, function(err, data) {
for (var i=0, len=data.length; i<len; ++i) {
data[i] = data[i]._doc; // if I don't do this, returned data
// has no 'text' property
data[i].text = data[i].name;
}
res.json({success: err, response:data});
});
更新
也许我误解了你原来的问题,但现在看起来你问题的性质已经改变了,所以下面的信息是不相关的,但我要离开它。 :)
我测试了你的代码,它对我来说工作正常。 当您设置不属于架构一部分的属性(或一些其他特殊属性)时,Mongoose不会执行任何特殊代码。 JavaScript目前不支持对尚不存在的属性的调用代码(因此,例如,Mongoose无法goo
属性的集合)。
所以,当你设置属性:
foo.goo = { c: 1 };
猫鼬不参与。 如果您的console.log
与您显示的代码不同,我可以看到它可能会错误地报告。
此外,当您send
结果作为JSON send
回时,将调用JSON.stringify
,它会在您的Mongoose模型上调用toString
。 发生这种情况时,Mongoose只会使用架构上定义的属性。 因此,默认情况下不会再发送其他属性。 你已经改变了data
数组的本质,直接指向Mongoose数据,所以它避免了这个问题。
关于正常行为的细节
当你使用Mongoose设置属性goo
,会发生很多事情。 Mongoose通过Object.defineProperty
创建属性获取者/设置者(一些文档)。 所以,当你设置你定义为[String]
的goo
属性时,会发生一些事情:
MongooseArray
)。 在你提供的例子中,因为你没有传递数组,所以它会被创建。 toString
。 因此,结果是文档现在包含一个数组,其中包含您传递的对象的toString
版本。
如果你检查了goo
属性的内容,你会发现它现在是一个单个元素的数组,它是一个包含[object Object]
的字符串。 如果您选择了更基本的类型或与目标属性存储类型相匹配,您会看到基本的相等性检查会起作用。