MongodbCursor,如何迭代Huge集合?

问题描述 投票:0回答:2

我有一个 MongoDb 数据库,里面有一个非常巨大的集合(超过 200 万个文档)。我想用光标迭代它。另外,在迭代过程中,我必须对当前文档执行一些操作。

var pending_push_cursor = collection.FindAllAs<PendingPush>();
foreach (PendingPush p_push in pending_push_cursor)
{
    operation_with(p_push)
}

主要问题是操作将元素排入队列,并且希望在某些时刻迭代暂停(几秒钟),以便让操作在添加新元素之前处理一些元素。

有没有一种方法可以以某种方式迭代光标,我可以暂停它,然后再恢复? MongodbCursor 保存最后访问的项目?我只知道 foreach 迭代,但是有这样的迭代吗?

while(pending_push_cursor.isLast()){
    PendingPush p_push= pending_push_cursor.getNext()
    operation_with(p_push)
 }

如果存在类似的东西,我可以保存最后查询的项目。 预先感谢

c# .net mongodb mongodb-.net-driver mongodb-query
2个回答
5
投票

使用 while 循环和光标的枚举器没有问题(这几乎就是 foreach 所做的,所以你可以继续使用它)。

您应该记住,光标在 10 分钟不活动后会超时,具体情况取决于您的具体情况。如果是这样,您可以禁用该特定光标的超时。

这是一个简单的例子:

cursor.SetFlags(QueryFlags.NoCursorTimeout);
using (var enumerator = cursor.GetEnumerator())
{
    while (enumerator.MoveNext())
    {
        var item = enumerator.Current;
        // logic

        if (shouldPause)
        {
            Thread.Sleep(1000);
        }
    }
}

0
投票

这是使用异步游标和批量大小为 10 的 C#/.NET 的最新解决方案:

var findOptions = new FindOptions<Player> { BatchSize = 10 };
using IAsyncCursor<Player> cursor = await _playerCollection.FindAsync(_ => true, findOptions);

while (await cursor.MoveNextAsync())
{
    var players = cursor.Current;

    foreach (var player in players)
    {
        Console.WriteLine($"Processing player {player.Id}");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.