mongoose .find()方法返回具有不需要的属性的对象

时间:2015-02-10 22:14:48

标签: javascript node.js mongoose properties

所以,我已经和猫鼬一起工作了一段时间,我发现了一些非常奇怪的东西。如果有人能够启发我会很棒。

问题是,当使用mongoose的.find()方法时,我得到的对象充满属性,我不知道它来自哪里(我猜测它们是建立的 - 在属性中,但无论如何)我只想通过属性I .select()进行迭代。得到它了?没有?好的......解释得更好:

我声明了我的架构和模型:

var mySchema = mongoose.Schema({
  name: String,
  prop1: String,
  prop2: String,
  prop3: String
})
var myModel = DB.model('myDataBase', mySchema)

然后我想找一个带有这个名字的文件,让我们说,约翰并找回除了这个名字之外的所有文件'领域,所以我去了:

myModel.find({name: 'John'}, '-name', function(err, results){
  log(results[0])
}

和log(results [0])记录

{ prop1: 'one',
  prop2: 'two',
  prop3: 'three' }

到目前为止,这么好。但问题是,现在我想迭代这些属性并逐一检查,我不确定有多少道具'每个结果都有,所以我想做类似的事情:

for(var key in results[0]){
  log(key)
}

所以,我希望它会记录' prop1',' prop2'和' prop3',但不!好吧,我得到道具1,2和3,但我也得到了很多其他的属性和功能,如:isNew,error,_maxListeners,_doc等。不仅这些额外的属性,我还得到了'名称&# 39;属性,我从选择中排除的属性(它被排除在外,如第一个日志中所示)。怪啊?

但是等等!还有更多!我在网上搜索过,发现有些人说'#34; Dude,在迭代对象属性时使用hasOwnProperty方法!"。所以我去了:

for (var key in results[0]){
  if (results[0].hasOwnProperty(key)) log(key)
}

日志结果是一些属性(具体来说:$ __,isNew,error,_maxListeners,_doc,_pres,_posts,save,_events)并且不包括我想要的任何道具。

我的问题是,我怎么能只迭代道具1,2和3,不包括这些,我不知道,内置属性和我在参数中明确排除的属性? (ps:我在想一个不需要将我的对象转换成数组的解决方案,如果可能的话)

此外,这不是一个问题,但出于好奇,这些属性来自哪里?为什么它们出现在for循环中而不是在我记录对象时?为什么我排除的属性(' -name')也出现在for循环中?如果它没有识别刚刚记录的属性,那么还有什么是onOwnProperty?

感谢您的时间和帮助! 再见!

4 个答案:

答案 0 :(得分:20)

除了Kevin B的回答,您可以将{lean: true}作为选项传递:

myModel.find({name: 'John'}, '-name', {lean: true}, function(err, results){
  log(results[0])
}

在MongoDB中,文档仅保存为对象。当Mongoose检索它们时,它会将它们转换为Mongoose文档。这样做会添加for循环中包含的所有密钥。这是允许您使用所有文档方法的原因。如果您不使用其中任何一个,lean是一个很好的选择,因为它会跳过整个过程,从而提高查询速度。 Potentially 3x as fast.

答案 1 :(得分:12)

在这种情况下.toObject足以让你的循环以你期望的方式工作。

myModel.find({name: 'John'}, '-name', function(err, results){
  log(results[0].toObject())
}

您最初得到的额外属性是由于results是模型实例的集合,这些实例附带了普通对象上不可用的其他属性和方法。这些属性和方法正在循环中出现。通过使用toObject,您将获得一个没有所有其他属性和方法的普通对象。

答案 2 :(得分:0)

答案很好,我想添加一个我添加到 dbUtils 类中的小打字稿实用程序。

getCleanObjectFromObjectOrDocument<T>(obj: T): T {
        return ((obj as unknown) as Document)?.toObject?.() ?? obj;
}

您可以在此处传递 mongoose 文档/子文档或任何纯 JS 对象,它会返回相应的 JS 对象。

答案 3 :(得分:0)

在 mongo 查询上使用 Lean() 或传递 {lean:true} 参数 例如myModel.find().lean()