find
游标的工作方式与findOne
游标的工作方式之间是否有区别。 findOne只是find().limit(1)
的包装吗?我一直在寻找它,也许有人知道mongodb是否有专门的方法。如果有区别,我正在使用mongodb的PHP API。#1 楼
根据我自己的基准,find().limit(1)
比findOne()
快几个数量级。MongoDB文档中有错误或
findOne()
中有错误。 findOne()
的执行效果与find().limit(N)
相似,其中N是查询将返回的文档数。我在想出为什么我的简单查询如此慢的原因时想出了这一点!更新:来自10gen(MongoDB)工程师的响应:
您正在执行的查询是非常不同的。查找查询
返回游标,这本质上是无操作的情况,因为没有返回实际数据(仅游标信息)。如果调用
findOne,则实际上是在返回数据并关闭
游标。文档绝对应该更加清晰:-)
更新:确实,如果检索到
find().limit(1)
文档,则数量级速度差似乎消失了。另外,我无法重现MongoDB JavaScript驱动程序的主要速度差异。我最初使用MongoDB Java驱动程序进行基准测试。#2 楼
findOne()
实际上是find().limit(1)
的语法糖,因为您实际上正在检索文档(而不是仅使用find()
返回游标)。 有关更多详细信息,请参见Leftium的答案和更新。
评论
好的,谢谢,我不喜欢在编程中使用synimus函数,而宁愿限制自己一个人,以便我的所有代码都易于跟踪。
– WojonsTech
2011年11月3日17:51
实际上,在基准测试中,findOne()比find()。limit(1)快一点。
–弗拉基米尔
2012年4月25日9:21
@ DairT'arg-如果您有资源或数据来支持此声明,请务必提供详细信息的答案!根据到目前为止的经验,只要您在两种情况下都检索文档,它们就应该相同。
–尼克·查玛斯(Nick Chammas)
2012年4月25日15:50
#3 楼
源代码可能有很多帮助。它是Java,但我想它也可以帮助。
findOne()
,DBObject findOne(DBObject o, DBObject fields, DBObject orderBy, ReadPreference readPref,
long maxTime, TimeUnit maxTimeUnit) {
QueryOpBuilder queryOpBuilder = new QueryOpBuilder().addQuery(o).addOrderBy(orderBy)
.addMaxTimeMS(MILLISECONDS.convert(maxTime, maxTimeUnit));
if (getDB().getMongo().isMongosConnection()) {
queryOpBuilder.addReadPreference(readPref);
}
Iterator<DBObject> i = find(queryOpBuilder.get(), fields, 0, -1, 0, getOptions(), readPref, getDecoder());
DBObject obj = (i.hasNext() ? i.next() : null);
if ( obj != null && ( fields != null && fields.keySet().size() > 0 ) ){
obj.markAsPartialObject();
}
return obj;
}
这是
find()
public DBCursor find( DBObject ref ){
return new DBCursor( this, ref, null, getReadPreference());
}
我们可以看到
findOne()
自己调用了find()
,获取了DBOject
中的所有i
,然后返回第一个。 #4 楼
您必须检查此链接...http://mongoosejs.com/docs/2.7.x/docs/finding-documents.html
查找-选项返回数组[]
findOne-选项返回文档{}
评论
很棒的发现。但是,重要的问题是:在正常编程(例如实际检索数据并关闭游标)的过程中,基准会自动处理findOne()必须执行的find()。limit(1)操作吗?反正为你呢?
–尼克·查玛斯(Nick Chammas)
2011年11月4日在6:07
@尼克:我认为额外的操作已涵盖在内。我正在查找一个随机文档(cookbook.mongodb.org/patterns/random-attribute),使用.next()获取该文档并将其从集合中删除。我没有手动关闭任何游标...
– Leftium
2011年11月4日在6:41
@WojonsTech:JS中的快速基准测试表明findOne()实际上更快。但是,结果可能因驱动程序/平台而异。例如,我无法重现最初使用Java驱动程序观察到的JS速度差的数量级。
– Leftium
2011年11月7日,下午5:24
Leftium,我将编辑您的答案以强调在实际检索文档时(通常会这样做),这两个功能实际上是相同的,就像文档中指出的那样。现在,某人可能会在答案的开头阅读粗体行并得出结论,如果他们想要检索一个文档,则findOne()比find()。limit(1)差,这是不正确的。
–尼克·查玛斯(Nick Chammas)
2012年4月18日15:57
@bigp这不是有效的性能提示,在实际检索文档时,这两种方法是相同的。
–JohnnyHK
19年1月15日在13:44