javascript mongoose .find() 方法返回具有不需要的属性的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28442920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
mongoose .find() method returns object with unwanted properties
提问by Thiago Loddi
so, I've been working with mongoose for some time and I found some really weird stuff going on. It would be great if someone could enlighten me.
所以,我已经和猫鼬一起工作了一段时间,我发现了一些非常奇怪的事情。如果有人能启发我,那就太好了。
The thing is, when using the .find() method of mongoose, the object I get as response is full of properties I don't know where It came from (I'm guessing they are built-in properties, but whatever) and I want to iterate only through the properties I .select(). Got it? No? ok... explaining better:
问题是,当使用 mongoose 的 .find() 方法时,我作为响应得到的对象充满了我不知道它来自哪里的属性(我猜它们是内置属性,但无论如何)和我只想遍历我 .select() 的属性。知道了?不?好的......解释得更好:
I have my schema and model declared:
我声明了我的架构和模型:
var mySchema = mongoose.Schema({
name: String,
prop1: String,
prop2: String,
prop3: String
})
var myModel = DB.model('myDataBase', mySchema)
Then I want to find a document with the name, let's say, John and retrieve all but the 'name' field, so I go:
然后我想找到一个带有名字的文档,比如说,John 并检索除“name”字段之外的所有内容,所以我去:
myModel.find({name: 'John'}, '-name', function(err, results){
log(results[0])
}
and log(results[0]) logs
和 log(results[0]) 日志
{ prop1: 'one',
prop2: 'two',
prop3: 'three' }
So far, so good. But the problems is, now I want to iterate through these properties and check one by one, and I don't know for sure how many 'props' each result will have, so I wanted to do something like:
到现在为止还挺好。但问题是,现在我想遍历这些属性并一一检查,但我不确定每个结果会有多少个“道具”,所以我想做一些类似的事情:
for(var key in results[0]){
log(key)
}
So, I'm hoping it will log 'prop1', 'prop2' and 'prop3', but no! Ok, I get props 1, 2 and 3, but also I get a lots of other properties and functions like: isNew, error, _maxListeners, _doc, etc. Not only these extras properties, I also get the 'name' property, the one I excluded from the selection (and it was excluded, like shown in the first log). Weird huh?
所以,我希望它会记录“prop1”、“prop2”和“prop3”,但不会!好的,我得到了 props 1、2 和 3,但我也得到了很多其他的属性和函数,比如:isNew、error、_maxListeners、_doc 等。不仅这些额外的属性,我还得到了“name”属性,我从选择中排除的一个(它被排除在外,如第一个日志中所示)。很奇怪吧?
But wait! There's more! I've searched online and found some people saying "Dude, when iterating through object properties use the hasOwnProperty method!". So there I went:
可是等等!还有更多!我在网上搜索过,发现有人说“老兄,在迭代对象属性时使用 hasOwnProperty 方法!”。所以我去了:
for (var key in results[0]){
if (results[0].hasOwnProperty(key)) log(key)
}
the log result is a few properties (to be specific: $__, isNew, error, _maxListeners, _doc, _pres, _posts, save, _events) and doesnt include any of the props I wanted in the first place.
日志结果是一些属性(具体来说:$__、isNew、error、_maxListeners、_doc、_pres、_posts、save、_events)并且不包括我首先想要的任何道具。
My question is, how can I iterate through only prop 1, 2 and 3, excluding these, I don't know, built-in properties and the one I explicitly excluded in the parameters? (ps: I was thinking of a solution that doesnt involve having to convert my object into an array, if thats possible)
我的问题是,如何仅迭代 prop 1、2 和 3,排除这些(我不知道)内置属性和我在参数中明确排除的属性?(ps:如果可能的话,我正在考虑一个不需要将我的对象转换为数组的解决方案)
Also, not a question per se, but for curiosity, where does these properties come from? Why do they appear in the for loop and not when I log the object? Why the property I excluded ('-name') also appears in the for loop? What the hell is hasOwnProperty for if it doesnt recognize the properties that were just logged?
此外,这本身不是一个问题,但出于好奇,这些属性从何而来?为什么它们出现在 for 循环中而不是在我记录对象时出现?为什么我排除的属性 ('-name') 也出现在 for 循环中?如果 hasOwnProperty 无法识别刚刚记录的属性,它到底是干什么的?
Thanks for your time and help! Bye!
感谢您的时间和帮助!再见!
回答by chrisbajorin
Alternatively to Kevin B's answer, you can pass {lean: true}
as an option:
{lean: true}
除了凯文 B 的回答,您可以作为一个选项传递:
myModel.find({name: 'John'}, '-name', {lean: true}, function(err, results){
log(results[0])
}
In MongoDB, the documents are saved simply as objects. When Mongoose retrieves them, it casts them into Mongoose documents. In doing so it adds all those keys that are being included in your for
loop. This is what allows you to use all the document methods. If you won't be using any of these, lean
is a great option as it skips that entire process, increasing query speed. Potentially 3x as fast.
在 MongoDB 中,文档被简单地保存为对象。当 Mongoose 检索它们时,它会将它们转换为 Mongoose 文档。这样做时,它会添加for
循环中包含的所有键。这就是允许您使用所有文档方法的原因。如果您不会使用其中任何一个,这lean
是一个不错的选择,因为它会跳过整个过程,从而提高查询速度。可能快 3 倍。
回答by Kevin B
In this case .toObject would be enough to let your loop work the way you expect.
在这种情况下, .toObject 足以让您的循环按您期望的方式工作。
myModel.find({name: 'John'}, '-name', function(err, results){
log(results[0].toObject())
}
The extra properties you were getting originally are due to the fact that results
is a collection of model instances that come with additional properties and methods that aren't available on normal objects. These properties and methods are what are coming up in your loop. By using toObject
, you get a plain object without all of those additional properties and methods.
您最初获得的额外属性是因为它results
是一个模型实例的集合,这些实例带有在普通对象上不可用的其他属性和方法。这些属性和方法是您的循环中出现的内容。通过使用toObject
,您可以获得一个没有所有这些附加属性和方法的普通对象。