Mongoose的toObject方法:{ virtuals: true }

11

我正在尝试学习MongoDB/Node,我注意到在一个schema中,我经常看到像这样的东西:

toObject: { virtuals: true }
toJSON: { virtuals: true }

这两行代码是什么意思?


你知道这里的一般惯例是“接受”帮助你的答案。那就是答案评分数字旁边的大“打钩”符号。我之所以说这个是因为你还没有接受任何一个问题的答案。它们不可能全部都是错误的,所以请接受它们。 - Neil Lunn
你有阅读关于这些选项的文档吗? - JohnnyHK
1个回答

20
这不是"MongoDB",而是特定于mongoose ODM的内容。
在模式定义中,Mongoose有一个“虚拟字段”("virtual" fields)的概念。这本质上允许这样做(从文档中明显地搜集):
var personSchema = new Schema({
    name: {
        first: String,
        last: String
    }
});

var Person = mongoose.model( "Person", personSchema );

但是假设你只想“存储”这些属性,然后有一个可以在代码中访问的名为“fullname”的东西。这就是“虚拟属性”发挥作用的地方:

personSchema.virtual("name.full").get(function () {
    return this.name.first + ' ' + this.name.last;
});

现在我们可以做这样的事情:
var bad = new Person({
    name: { "first": "Walter", "last": "White" }
});

console.log("%s is insane", bad.name.full); // Walter White is insane

因此,name.full实际上并不存在于数据中,它只是代码中的模式表示。但当然,“绑定”到一个函数,该函数使用对象中实际存在的数据制作方法,根据方法中的代码组合两个字段返回一个值。
这基本上就是“虚拟”字段的含义。它们实际上是在文档“对象”上定义的“方法”,用于展示在数据库中未“存储”或持久化的值。通常它们基于来自数据存储的实际持久化值。
但是,为了真正澄清您的直接问题。默认情况下,Mongoose仅基于“存储”的字段序列化其内部对象结构的内容。因此,那两行代码的“真正”含义是:
  1. toObject(): This produces a "plain" or "raw" representation of the object data without all the other "mongoose magic" parts of the extended object. But the purpose of "virtuals" is to make those methods part of the object returned. Basically just the plain object, called as:

     var model = Model.new({ "name": { "first": "Walter", "last": "White" });
     console.log( model.toObject() );
    
  2. toJSON(): You can call this method explicitly and just as shown above, but it's most common usage is from a JSON parser like below where it is implicitly called. The same principles apply as above. The "virtuals" includes the result of those methods in the serialized output, such as:

     var model = Model.new({ "name": { "first": "Walter", "last": "White" });
     JSON.stringify( model, undefined, 2 );
    
在第二种情况下,对象上会发生"隐式"调用.toJSON()方法。配置告诉该方法不仅包括对象中存在的数据或"字段",还要包括定义的"虚拟"方法及其输出结果。同样适用于.toObject()

谢谢,但是"set('toObject': { virtuals: true })"具体是做什么的?我了解虚拟概念,但这对我来说看起来就像你只是设置一个名为'toObject'的对象键并将其设置为一个数据虚拟:true的对象,它在这里想实现什么? - oheas
感谢您编辑答案,以解释 toObject() 和 toJSON()。 - oheas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接