我是新來的MongoDB(及其DOTNET核心C#驅動程序),我有關於IAsyncCursor行爲以下問題:MongoDB C#驅動程序IAsyncCursor <BsonDocument>行爲?
從官方文檔: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循環更加一致,因此我自己的代碼片段不必(冗餘地)檢查「當前」做」。我發現「IAsyncCursor.First()」確實返回了「第一個」文檔 - 我現在猜測「First()」方法實際上是在內部執行「MoveNext」,並返回第一個「當前」批次的文件。
此外,因爲我使用的是「FindAsync」,並且如果找不到基於我的過濾器的文檔,返回的IAsyncCursor「null」還是「MoveNext」將返回false?我可以假設FindAsync返回的IAsyncCursor始終是一個有效的對象,所以我不必過於檢查null,只需檢查「MoveNext()」或「First()」的返回值?
您可以讓MongoDB專家對此有所瞭解嗎?
謝謝!
感謝您的回答,我知道並且大部分都在使用ForEachAsync。但是,我的問題更多地是關於MoveNext的行爲,不完全是我應該使用ForEachAsync來替換示例代碼中的vanilla while循環。或者你可以更具體地瞭解MoveNext的行爲,我的問題更準確地關注? – Dejavu
@Dejavu沒問題,你說你是MongoDB和驅動程序的新手,所以我認爲你可能會讓事情比他們需要的更難。 – JohnnyHK