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