为什么我不能使用下划线(_)扩展来更新未在模式定义中定义属性的mongoose模型。有办法解决这个问题吗?
节点模型:
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var NodeSchema = new Schema({
label: {type : String, default : 'none'}
}, { strict: false })
mongoose.model('Node', NodeSchema)
节点控制器:
var node = new Node();
node = _.extend(node, {"EXTENDNOTinSchema":"TRUE"});
console.log("extend: " + node);
node.set("SETNOTinSchema","TRUE");
console.log("set: " + node);
控制台输出:
extend: { __v: 0,
_id: 50bb05656880a68976000001,
label: 'none' }
set: { __v: 0,
_id: 50bb05656880a68976000001,
label: 'none'
SETNOTinSchema: TRUE}
答案 0 :(得分:7)
这种情况正在发生,因为如果模式中没有某些东西,那么Mongoose就不能使用“defineProperty”,这会像其他任何一样对待赋值。
首先,只是为了清楚。
node = _.extend(node, {"EXTENDNOTinSchema":"TRUE"});
与此相同:
node['EXTENDNOTinSchema'] = 'TRUE';
在一般情况下,这与此完全不同。
node.set("SETNOTinSchema","TRUE");
诀窍是Mongoose很聪明,使用我上面提到的defineProperty
函数,它可以绑定一个函数来调用这样的东西:
node['INSCHEMA'] = 'something';
但是对于那些不在模式中的东西,它不能这样做,所以赋值就像普通的赋值一样。
绊倒你的部分我认为console.log
正在做一些隐藏的魔法。如果您查看docs,console.log
将调用传递给它的对象的inspect
方法。在Mongoose的情况下,它的模型不直接在模型对象上存储属性,它们存储在内部属性中。当您使用defineProperty
或调用set
分配给正在监视的属性时,它会将值存储在内部对象上。当您log
模型时,inspect
会打印出内部模型内容,使模型值看起来就像存储在对象上一样。
所以当你这样做时
console.log(node);
你真正看到的是
console.log(node.somehiddenproperty);
因此,您的问题的答案实际上是,如果您有一堆不在架构中的值,则无法使用_.extend
。相反,只需使用set
因为它无论如何都需要一个对象。
node.set({"EXTENDNOTinSchema":"TRUE"});