Mongoose toObject和toJSON有什么区别?

ste*_*red 17 mongoose

toObjectMongoose文档列出了功能,选项,并提供了功能的示例toObject.

Mongoose文档toJSON说明选项与toObject相同,但没有解释是什么toJSON. 在其他地方,文件说

toJSON与toObject选项完全相同,但仅在调用文档的toJSON方法时适用.

toJSON别名toObject吗?如果没有,有什么区别?

Joh*_*yHK 18

看一下源代码就会发现两个方法都调用了一个内部$toObject方法,但是toJSON传递了第二个true参数:

Document.prototype.toObject = function (options) {
  return this.$toObject(options);
};
...
Document.prototype.toJSON = function (options) {
  return this.$toObject(options, true);
};
Run Code Online (Sandbox Code Playgroud)

第二个参数确定是$toObject使用默认值toJSON还是toObject模式选项.因此,除非这些模式选项的配置不同,否则这两种方法是相同的.

  • 作为旁注,使用toJSON的不同配置实际上是有意义的 - 您可以在从控制器返回对象之前进行一些转换(在express res.json(object)中调用JSON.stringify,即object.toJSON) - 例如depopulate一些条目,以避免堆栈溢出... (2认同)

Anh*_*Cao 5

正如JohnnyHK的回答者所说,toJSON和之间没有区别toObject。我的猜测是,toJSON创建该JSON.stringify方法是为了支持该方法。

MDN文档开始,如果对象具有toJSON作为函数的属性,JSON.stringify则将使用该toJSON函数序列化对象而不是对象本身。


aer*_*ino 5

对于我的用例,这就是我得到的:

  • .toJSON的优点是它被自动使用JSON.stringify。如果将架构​​选项设置toJSON为重塑选项,则当您使用该架构对文档进行字符串化时,将构建具有正确形状的对象

  • .toObject的优点是有时JSON.stringify会在断开文档和模式之间的链接后运行,因此不会发生重新整形。在这种情况下,您只需使用toObject这些选项调用文档方法即可获取具有正确形状的对象。

例子

  • 具有:
const reshapingOptions = {

    // include .id (it's a virtual)
    virtuals: true,

    // exclude .__v
    versionKey: false,

    // exclude ._id
    transform: function (doc, ret) {
        delete ret._id;
        return ret;
    },

};

const friendSchema = mongoose.Schema({ 
    givenName: String,
    familyName: String,
}, { toJSON: reshapingOptions });

const friendModel = mongoose.model('Friend', friendSchema);

const john = friendModel.findOne({ givenName: 'John' });
if (!john) {
    res.status(404).json({ error: 'No John Found' });
}
Run Code Online (Sandbox Code Playgroud)
{
    "id": "...",
    "givenName": "John",
    "familyName": "Doe"
}
Run Code Online (Sandbox Code Playgroud)
{
    "_id": "...",
    "givenName": "John",
    "familyName": "Doe",
    "__v": 0,
    "role": "dummy friend"
}
Run Code Online (Sandbox Code Playgroud)
{
    "id": "...",
    "givenName": "John",
    "familyName": "Doe",
    "role": "dummy friend"
}
Run Code Online (Sandbox Code Playgroud)