繁体   English   中英

MongoDB C#驱动程序IAsyncCursor <BsonDocument> 行为?

[英]MongoDB C# driver IAsyncCursor<BsonDocument> behavior?

我是MongoDB(及其dotnet核心C#驱动程序)的新手,关于IAsyncCursor行为,我有以下问题:

从官方文档: https ://docs.mongodb.com/getting-started/csharp/query/,似乎建议通过IAsyncCursor进行迭代的方法是:

var collection = _database.GetCollection<BsonDocument>("restaurants");
var filter = new BsonDocument();
var count = 0;
using (var cursor = await collection.FindAsync(filter))
{
    while (await cursor.MoveNextAsync())
    {
        var batch = cursor.Current;
        foreach (var document in batch)
        {
            // process document
            count++;
        }
    }
}

但是,似乎要获取返回的文档的“当前”批次,而while循环首先显示“ MoveNextAsync”,“ MoveNextAsync”是否跳过“当前”批次? 或者从逻辑上讲,以下修改后的代码片段更有意义吗?

var collection = _database.GetCollection<BsonDocument>("restaurants");
var filter = new BsonDocument();
var count = 0;
using (var cursor = await collection.FindAsync(filter))
{
    do
    {
        if (cursor.Current != null)
        {
            var batch = cursor.Current;
            foreach (var document in batch)
            {
                // process document
                count++;
            }
        }
    }
    while (await cursor.MoveNextAsync())
}

我的理解是,游标应该从已经指向“当前”批次(如果有)开始,并且我应该首先处理“当前”批次是什么,然后再移至下一批文档(如果有)。

但是对于我可以在网上找到的所有资源,似乎迭代总是先执行“ MoveNext”,然后再进行批处理-这给我的印象是FindAsync返回的IAsyncCursor开始指向实际位置之前的位置。必须先调用“当前”(或第一批)文档,然后首先调用“ MoveNext”才能将光标移到实际当前位置。

从编码的角度来看,首先调用“ MoveNext”可以使while循环更加一致,因此我自己的代码段不必(冗余地)检查“ do”体内“ current”的有效性。

但是,我确实发现“ IAsyncCursor.First()”确实返回了“第一个”文档-现在,我猜测“ First()”方法实际上在内部进行了“ MoveNext”操作,并返回了“当前”批次。

另外,当我使用“ FindAsync”时,如果找不到基于我的过滤器的文档,返回的IAsyncCursor是否为“ null”或“ MoveNext”是否将返回false? 我是否可以假定FindAsync返回的IAsyncCursor始终是有效对象,所以我不必过多地检查null,而只需检查“ MoveNext()”或“ First()”的返回值?

您能不能请MongoDB专家对此发表见解?

谢谢!

第一个代码示例正确,并且不会跳过第一批。 但是,如果要显式控制获取批处理,则仅需要直接使用MoveNextAsync

否则,使用ForEachAsync会更简单, ForEachAsync它为您带来了这种复杂性:

using (var cursor = await collection.FindAsync(filter))
{
    await cursor.ForEachAsync(document =>
    {
        // process document
        count++;
    }
}

此处查看ForEachAsync源。

如源代码所示, ForEachAsync获取光标的所有权并为您处理它,因此您也可以根据需要省略自己的using

因此,从我的所有测试和在网上找到的资源来看,似乎我的原始观察是正确的,即FindAsync方法返回的IAsyncCursor最初以中立状态(“当前”似乎为空)开始,即MoveNext(Async )必须先调用,以使其移动到“当前”将包含第一批文档的第一批-我还观察到不存在的查找结果,MoveNext将使光标的“当前” 不为 null ,但Current.Count()将返回0,这意味着即使MoveNext成功执行,但该批次中也没有文档-这以某种方式暴露了API设计一致性的问题-“ MoveNext”应该返回false表示存在没有更多文档,或者在成功执行“ MoveNext”之后,如果“ Current”为null表示没有文档,或者“ Current”为非null,则Current.Count()== 0表示没有文档文件? 现在,我正在检查所有三个条件,以确保我的代码是安全的,同时我认为使“ MoveNext”已经返回false表示没有其他文档将是最直观的API。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM