如何将Mongoose文档转换为普通对象?

时间:2011-09-21 16:40:44

标签: node.js mongoose

我有一个来自mongoose的文档发现我想在JSON编码之前扩展并作为响应发送出去。如果我尝试向doc添加属性,则会被忽略。这些属性不会出现在Object.getOwnPropertyNames(doc)中,无法正常扩展。奇怪的是JSON.parse(JSON.encode(doc))工作并返回一个具有所有正确属性的对象。有更好的方法吗?

9 个答案:

答案 0 :(得分:246)

Mongoose Model继承自Document s,其toObject()方法。我相信你所寻找的应该是doc.toObject()的结果。

http://mongoosejs.com/docs/api.html#document_Document-toObject

答案 1 :(得分:179)

另一种方法是通过在查询链中使用lean()告诉Mongoose您需要的只是返回文档的纯JavaScript版本。通过这种方式,Mongoose跳过了创建完整模型实例的步骤,您可以直接获得可以修改的doc

MyModel.findOne().lean().exec(function(err, doc) {
    doc.addedProperty = 'foobar';
    res.json(doc);
});

答案 2 :(得分:25)

如果属性不在模型中的快速方式:

document.set( key,value, { strict: false });

答案 3 :(得分:4)

精益 选项告诉 Mongoose 跳过对结果文档进行补水。这使得查询速度更快,内存占用更少,但结果文档是普通的旧 JavaScript 对象 (POJO),而不是 Mongoose 文档。

const leanDoc = await MyModel.findOne().lean();

不需要使用 JSON.parse() 方法

答案 4 :(得分:3)

在某些情况下,如@JohnnyHK所建议,您可能希望将对象作为纯Java脚本获取。 如Mongoose Documentation中所述,还有另一种方法可以直接将数据作为对象进行查询:

const docs = await Model.find().lean();

但是,作为一个选项对象,请参见第三个参数的find() docs

const docs = await Model.find({},null,{lean:true});

它在以下功能上可用:find()findOne()findById()findOneAndUpdate()findByIdAndUpdate()

答案 5 :(得分:2)

解决此类问题的更好方法是使用doc.toObject()这样的

doc.toObject({ getters: true })

其他选项包括:

  • getters:应用所有getter(路径和虚拟getter)
  • virtuals:应用虚拟getter(可以覆盖getter选项)
  • minimize:删除空对象(默认为true)
  • transform:转换函数,在返回
  • 之前应用于生成的文档
  • depopulate:取消填充所有填充的路径,将其替换为原始引用(默认为false)
  • versionKey:是否包含版本密钥(默认为true)

所以例如你可以说

Model.findOne().exec((err, doc) => {
   if (!err) {
      doc.toObject({ getters: true })
      console.log('doc _id:', doc._id)
   }
})

现在它会起作用。

供参考,请参阅:http://mongoosejs.com/docs/api.html#document_Document-toObject

答案 6 :(得分:1)

您还可以对对象进行字符串化,然后再次解析以生成普通对象。 例如:-

const obj = JSON.parse(JSON.stringify(mongoObj))

答案 7 :(得分:0)

要从Mongoose文档中获取普通对象,我按如下方式使用了_doc属性

mongooseDoc._doc  //returns plain json object

我尝试使用toObject,但它为我提供了功能,参数和我不需要的所有其他东西。

答案 8 :(得分:0)

一种方便的方法是将其直接应用于模型架构。

如猫鼬文档所述:

“默认情况下,要将这些选项应用于架构的每个文档,请将架构的toObject选项设置为相同的参数。”

schema.set('toObject', { virtuals: true })