Hi, @bharath_narayan,
Welcome to the MongoDB Community Forums.
When a query fetches documents from MongoDB those documents are returned in 16MB batches. The initial query returns the first 16MB batch along with a cursorId, which can be further iterated by calling getMore with that cursorId. Fetching additional results is handled automatically by the driver by internally calling getMore when the current bath is exhausted.
By default MongoDB terminates idle cursors after 10 minutes. Thus if it takes you more than 10 minutes to process a 16MB batch, the getMore will fail because the idle cursor has been killed.
There are a few possible solutions:
- The easiest solution is to retrieve all the data prior to processing the results. This is only feasible if the retrieved data can all fit into memory. Simply adding
ToList()(e.g.collection.AsQueryable().ToList()) will retrieve all results into memory prior to processing each one. - Specify a smaller batch size via
AsQueryable(new AggregationOptions { BatchSize = N })where N is the number of documents to pull back at a time. By reducing the number of documents per batch, you can force the driver to callgetMoreprior to the 10-minute cursor timeout. - Page through the results explicitly by implementing pagination supported by a sort. (e.g.
collection.AsQueryable().Where(x => x.SortField > lastSeen).OrderBy(x => x.SortField).Take(10)) - Adjust the server parameter
cursorTimeoutMillisto a higher value. Not recommended, but a potential quick fix if you’re trying to do a one-time run on your local machine.
Hope this helps.
Sincerely,
James