mongoose:“_doc”怎么了?

看起来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 

从本质上讲,任何时候你试图处理一个Mongoose模型的属性,而不是在模型的模式中定义的a),或者b)被定义为相同的types(数组,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}); }); 

更新

也许我误解了你原来的问题,但是现在看起来你问题的本质已经改变了,所以下面的信息是不相关的,但是我要离开它了。 🙂

我testing了你的代码,对我来说工作正常。 当您设置不属于架构的属性(或一些其他特殊属性)时,Mongoose不会执行任何特殊的代码。 JavaScript目前不支持对尚不存在的属性的调用代码(例如,Mongoose无法goo属性的设置)。

所以,当你设置属性:

 foo.goo = { c: 1 }; 

mongoose不参与。 如果您的console.log与您显示的代码不同,我可以看到它可能会错误地报告。

此外,当您send结果作为JSON send回时,将调用JSON.stringify ,它在您的Mongoose模型上调用toString 。 当发生这种情况时,Mongoose只使用架构上定义的属性。 所以,默认情况下不会有其他属性被发回。 你已经改变了data数组的性质,直接指向Mongoose数据,所以它避免了这个问题。

关于正常行为的细节

当你使用Mongoose设置属性goo ,会发生很多事情。 Mongoose通过Object.defineProperty (一些文档 )创build属性获取器/设置器。 所以,当你设置你定义为[String]goo属性时,会发生一些事情:

  1. 在将值设置到对象实例之前调用Mongoose代码(与简单的JavaScript对象不同)
  2. Mongoose创build一个数组(可选)来存储将包含数组数据的数据( MongooseArray )。 在你提供的例子中,因为你没有传递一个数组,所以它会被创build。
  3. mongoose会试图将你的数据转换为正确的types
  4. 它将在作为演员一部分传递的数据上调用toString

因此,结果是文档现在包含一个数组,其中包含您传递的对象的toString版本。

如果你检查了goo属性的内容,你会发现它现在是一个单个元素的数组,它是一个包含[object Object]的string。 如果你select了一个更基本的types或匹配的目标属性存储types,你会看到一个基本的平等检查工作。