使用MongoDB C# Driver v2.17.1遍历文档时遇MongoCursorNotFoundException求助
解决方案:MongoDB C# Driver 游标找不到异常(MongoCursorNotFoundException)
问题原因
你的代码使用AsQueryable()遍历文档,单次迭代耗时2-5秒,处理1400条文档的累计时间远超MongoDB服务器默认游标超时时间(10分钟)。服务器会自动销毁闲置超时的游标,当程序尝试获取下一批数据时,就会抛出游标找不到的异常。
具体解决方案
1. 延长游标超时时间
通过FindOptions设置更长的游标超时时间,或临时禁用游标超时(注意用完必须释放游标):
string connectionString = @"mongodb://localhost:27017/"; var dbClient = new MongoClient(connectionString); var db_sample = dbClient.GetDatabase("mongodbname"); var collection = db_sample.GetCollection<DataModel>("mongodbcollectionname"); // 设置游标超时为2小时(根据你的处理总时长调整) var options = new FindOptions<DataModel> { MaxTime = TimeSpan.FromHours(2) }; // 或者禁用游标超时(不推荐长期使用,需确保游标被释放) // options.NoCursorTimeout = true; using (var cursor = collection.Find(Builders<DataModel>.Filter.Empty, options)) { while (cursor.MoveNext()) { foreach (var cdm in cursor.Current) { // 文档处理与更新逻辑 } } }
2. 批量拉取+批量更新
减少游标闲置时间,每次拉取一批文档,批量处理后批量更新,大幅缩短总耗时:
int batchSize = 500; // 可根据内存调整批次大小 var filter = Builders<DataModel>.Filter.Empty; var cursor = collection.Find(filter).BatchSize(batchSize); while (cursor.MoveNext()) { var batch = cursor.Current.ToList(); var updateBatch = new List<UpdateOneModel<DataModel>>(); foreach (var cdm in batch) { // 生成更新操作 var update = Builders<DataModel>.Update .Set(x => x.TargetField, UpdatedValue) // 替换为你的更新逻辑 .Set(x => x.AnotherField, AnotherValue); updateBatch.Add(new UpdateOneModel<DataModel>( Builders<DataModel>.Filter.Eq(x => x.Id, cdm.Id), update )); } // 批量提交更新 if (updateBatch.Count > 0) { collection.BulkWrite(updateBatch); } }
3. 改用异步遍历提升效率
异步操作避免阻塞,减少游标等待时间,同时利用MongoDB驱动的异步优化:
await collection.Find(Builders<DataModel>.Filter.Empty) .ForEachAsync(async cdm => { // 异步处理与更新 var update = Builders<DataModel>.Update.Set(x => x.TargetField, UpdatedValue); await collection.UpdateOneAsync(Builders<DataModel>.Filter.Eq(x => x.Id, cdm.Id), update); });
4. 优化单条文档处理逻辑(根本解决)
将单次迭代耗时从2-5秒降低,从根源避免游标超时:
- 缓存循环内重复查询的数据(如关联表数据)
- 减少不必要的IO操作(文件读写、网络请求等)
- 优化计算逻辑,必要时采用并行处理(注意线程安全)
- 避免在循环内创建不必要的对象或重复初始化资源
内容的提问来源于stack exchange,提问作者bharathN
相关产品推荐
相关产品推荐

