mongoose.find()方法返回带有不需要的属性的对象。
mongoose.find()方法返回带有不需要的属性的对象。
最近我一直在使用mongoose,发现了一些非常奇怪的问题。如果有人能够给我一点启示那就太好了。\n问题是,当使用mongoose的.find()方法时,我得到的响应对象中充满了我不知道从哪里来的属性(我猜它们是内置属性,但无论如何),我只想迭代我用.select()选择的属性。明白了吗?还不明白?好吧...我来解释清楚一点:\n我已经声明了我的模式和模型:\nvar mySchema = mongoose.Schema({\n name: String,\n prop1: String,\n prop2: String,\n prop3: String\n})\nvar myModel = DB.model(\'myDataBase\', mySchema)\n然后我想通过名字查找一个文档,假设叫John,然后获取除了\'name\'字段之外的所有字段,所以我这样做:\nmyModel.find({name: \'John\'}, \'-name\', function(err, results){\n log(results[0])\n}\nlog(results[0])会输出\n{ prop1: \'one\',\n prop2: \'two\',\n prop3: \'three\' }\n到目前为止,一切都很好。但问题是,现在我想迭代这些属性并逐个检查,但我不确定每个结果会有多少个\'prop\',所以我想做一些像这样的操作:\nfor(var key in results[0]){\n log(key)\n}\n所以,我希望它会输出\'prop1\'、\'prop2\'和\'prop3\',但不!好吧,我得到了props 1、2和3,但我还得到了很多其他属性和函数,比如:isNew、error、_maxListeners、_doc等。不仅有这些额外的属性,我还得到了\'name\'属性,这是我在选择中排除的一个属性(而且它确实被排除了,就像第一个log所示)。奇怪吧?\n但等等!还有更多!我在网上搜索了一下,发现有些人说\"伙计,当遍历对象属性时使用hasOwnProperty方法!\"所以我就试了一下:\nfor (var key in results[0]){\n if (results[0].hasOwnProperty(key)) log(key)\n}\nlog的结果是一些属性(具体来说:$__、isNew、error、_maxListeners、_doc、_pres、_posts、save、_events),并不包括我一开始想要的任何props。\n我的问题是,我如何只迭代prop1、prop2和prop3,排除这些我不知道的内置属性和我在参数中明确排除的属性呢?(附注:我想要一个不需要将对象转换为数组的解决方案,如果可能的话)\n另外,并不是一个问题,但是出于好奇,这些属性从哪里来的?为什么它们在for循环中出现,而在我打印对象时却没有出现?为什么我排除的属性(\'-name\')也出现在for循环中?如果hasOwnProperty不能识别刚刚打印的属性,它到底有什么用呢?\n谢谢你的时间和帮助!\n再见!
mongoose的.find()方法在执行查询后返回一个对象,但有时返回的对象中可能会包含一些不需要的属性。这个问题的出现原因是mongoose在执行查询时,默认会将查询结果转换为mongoose文档对象,这些文档对象包含了很多mongoose的内部属性和方法,而我们在实际应用中可能只关心查询结果的数据部分。
解决这个问题的方法是使用mongoose的lean()方法或传递{lean:true}参数给查询方法。lean()方法告诉mongoose返回一个普通的JavaScript对象,而不是mongoose文档对象。这样返回的对象中就不会包含mongoose的内部属性和方法,只包含查询结果的数据部分。
下面是一个使用lean()方法解决问题的示例代码:
myModel.find().lean()
在这个示例中,我们调用了myModel的find()方法,并链式调用了lean()方法。这样返回的查询结果对象就是一个普通的JavaScript对象,不会包含不需要的属性。
另外,我们也可以在查询方法中传递{lean:true}参数来达到相同的效果。例如:
myModel.find({}, null, {lean:true}, function(err, docs) { // 处理查询结果 });
在这个示例中,我们在查询方法的第三个参数位置传递了{lean:true}参数,告诉mongoose返回一个普通的JavaScript对象。
总之,通过使用mongoose的lean()方法或传递{lean:true}参数给查询方法,我们可以解决mongoose的.find()方法返回对象中包含不需要的属性的问题。这样返回的结果对象就只包含查询结果的数据部分,更符合我们的实际需求。
问题出现的原因是,当使用Mongoose的.find()方法返回对象时,它会将查询结果转换为Mongoose文档,从而添加了一些额外的属性。这些额外的属性在使用循环遍历时都会被包含进来。如果不需要使用这些文档方法,可以使用lean
选项来跳过这个过程,从而提高查询速度。
解决方法是在查询时传递{lean: true}
作为选项,如下所示:
myModel.find({name: 'John'}, '-name', {lean: true}, function(err, results){ log(results[0]) }
另外,也可以在查询链中使用.lean()
方法来实现相同的效果,如下所示:
await myModel.find({status: 'requested'}).lean().exec();
根据问题中的讨论,{lean: true}
只能作为find()
方法的第三个参数传递,而不能像await myModel.find({status: 'requested'}, {lean: true});
这样直接传递。
通过使用{lean: true}
选项,可以解决这个问题,从而返回不包含额外属性的对象,提高查询速度。