【问题标题】:Mongo C# - Where is FindOne?Mongo C# - FindOne 在哪里?
【发布时间】: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<> 上找不到FindOneFindOneAsync 方法,所以我怀疑.Find(...).SingleAsync() 只是在执行mongo find 函数。我可以看到有FindOneAndUpdateFindOneAndDeleteFindOneAndReplace,但没有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 秒。

标签: c# mongodb


【解决方案1】:

添加Limit(1) 为我修复了它:

await _collection.Find(filterDefinition).Limit(1).SingleAsync();

我原以为 .SingleAsync() 会在其中执行 Limit(1) ,但它似乎改为执行 .Limit(2) 。这足以使我的查询从 0 秒变为 8 秒。

【讨论】:

  • 它正在执行限制 2 以确保只有一个元素。如果它只取一个,它不会知道是否有多个,因为SingleAsync() 的目的是返回一个或抛出一个。试试FirstAsync()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 2020-01-18
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
相关资源
最近更新 更多