Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-1724

IAsyncCursor Current property sometimes returns an empty batch

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: 2.2.4
    • Component/s: None
    • None
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      The documentation for querying data with the c# driver here appears to sometimes fail if documents are too large, because MoveNextAsync() wrongly returns true, even though there are no more documents.

      This can cause issues if you rely on MoveNextAsync to always behave as expected, and attempt to batch insert the results of cursor.Current(), as in the below example:

      var initialColl = _database.GetCollection<BsonDocument>("initialCollection");
      
                  await
                      initialColl.InsertManyAsync(new[]
                      {
                          new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                          new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                          new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                          new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                          new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                          new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                      });
      
                  var numDocuments = await initialColl.CountAsync(x => true);
                  if (numDocuments > 0)
                  {
                      var backup = _database.GetCollection<BsonDocument>("initialCollection_backup");
                      var count = 0;
                      using (var cursor = await initialColl.FindAsync(x => true))
                      {
                          while (await cursor.MoveNextAsync())
                          {
                              var docBatch = cursor.Current.ToList();
                              count += docBatch.Count();
                              await backup.InsertManyAsync(docBatch);
                          }
                      }
                  }
      

      In this example, the line:

      var docBatch = cursor.Current.ToList()
      

      retrieves all six items on the first iteration of the while loop, the loop then enters a second iteration where it retrieves an empty set of documents. The code then crashes on attempting to insert this empty set into the backup collection.

      There are trivial workarounds (e.g. only inserting documents if any are returned, 'foreach'ing over the cursor etc.).

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            TKilFre Tristan Kilani-Freeman [X]
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: