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

我有一个文档从猫鼬发现,我想在JSON编码和发送作为响应之前扩展。如果我尝试向文档添加属性,它会被忽略。属性不会出现在Object.getOwnPropertyNames(doc)中,因此不可能进行正常的扩展。奇怪的是JSON.parse(JSON.encode(doc))工作并返回一个具有所有正确属性的对象。还有更好的办法吗?

186294 次浏览

Mongoose的__abc0继承自__abc1,后者有一个toObject()方法。我相信你要找的应该是doc.toObject()的结果。

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

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

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

如果属性不在模型中,快速的方法是:

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

解决这类问题的更好方法是像这样使用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

为了从Mongoose文档中获取普通对象,我使用_doc属性,如下所示

mongooseDoc._doc  //returns plain json object

我尝试了toObject,但它给了我函数,参数和所有其他我不需要的东西。

你也可以对对象进行字符串化,然后再次解析以生成正常的对象。 例如:-

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

JohnnyHK建议:

在某些情况下,正如@JohnnyHK所建议的,你会想要以纯Javascript的形式获取对象。 如猫鼬的文档中所述,还有另一种直接作为对象查询数据的替代方法:

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

有条件地返回Plain Object:

此外,如果有人想有条件地转向一个对象,它也可以作为option参数,请参阅第三个参数的find()文档:

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

它可以在函数find()findOne()findById()findOneAndUpdate()findByIdAndUpdate()上使用。

注意:

值得一提的是,_id属性不是一个字符串对象,就像你会做JSON.parse(JSON.stringify(object))一样,而是一个来自猫鼬类型的ObjectId,所以当它与字符串比较时,将它转换为前面的字符串:String(object._id) === otherStringId

精益选项告诉Mongoose跳过结果文档的水化。这使得查询更快,内存消耗更少,但结果文档是普通的旧JavaScript对象(pojo),而不是Mongoose文档。

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

没有必要使用JSON.parse()方法

我一直在我的文档上使用toObject方法,但没有成功。 我需要将flattenMap属性添加到true中,以最终获得一个POJO
const data = document.data.toObject({ flattenMaps: true });