【发布时间】:2018-01-09 07:40:33
【问题描述】:
我无法理解如何在 Mongo C# 2.4 驱动程序中执行 findOne 操作。
我有一个包含超过 910 万个平面文档的集合。当我在 Robomongo 中执行findOne 时,查询需要 0 秒,并返回我想要的结果。
在 C# 中,这大约需要 7-8 秒。
目前我正在实现这样的查找:
var result = await _collection.Find(filterDefinition).SingleAsync();
这需要 7 到 8 秒。
Mongo 查询 - 查找一个 - 0 秒
.findOne({ipFrom: { $lte: 1436497981 }, ipTo: { $gte: 1436497981 }});
Mongo 查询 - 查找 - 7.4 秒
.find({ipFrom: { $lte: 1436497981 }, ipTo: { $gte: 1436497981 }});
我在IMongoCollection<> 上找不到FindOne 或FindOneAsync 方法,所以我怀疑.Find(...).SingleAsync() 只是在执行mongo find 函数。我可以看到有FindOneAndUpdate、FindOneAndDelete和FindOneAndReplace,但没有FindOne。
我用于查询的过滤器定义如下:
var filter = Builders<TLocationEntity>.Filter;
var filterDefinition = filter.And(
filter.Lte("ipFrom", ipValue),
filter.Gte("ipTo", ipValue)
);
基本上,在 C# 驱动程序中执行findOne 的正确方法是什么?
【问题讨论】:
-
好吧,“从技术上讲”,shell 中的
.findOne()和其他所有 API 也是如此。实际上,您只需键入不带括号()的db.collection.findOne就可以在 shell 中看到这一点。这将告诉您.find()实际上是底层 API 中唯一的实际调用。如果您想要“苹果与苹果”,您需要.find({ipFrom: { $lte: 1436497981 }, ipTo: { $gte: 1436497981 }}).limit(1)基本上比较相同的东西。 -
@NeilLunn 够了,谢谢!自从我接触 Mongo 已经好几年了,所以我有点生疏了!将
.Limit(1)添加到我的.Find()方法可以显着提高性能。 -
这基本上就是
.SingleAsync()之类的东西。所以从技术上讲,一切都只是用于查找的“光标修饰符”。 API 进行了一些更改,以使其在不同语言之间的一致性更加普遍。 -
@NeilLunn 查看
SingleAsync的源代码,看起来它执行的是find.Limit(2),而不是find.Limit(1)。如果我在 mongo shell 中使用.limit(2)运行查询,大约需要 8 秒,如果我将其更改为 1 则需要 0 秒。