除非您有大量数据,否则此问题不易复制。
我有很多查询是返回大量数据的聚合(数千万条结果)。这些查询的结果显然太大而无法存储在内存中,因此当我返回结果时,我会执行ToEnumerable()。当我遍历返回的IEnumberable时,我最终得到一个" MongoDB.Driver.MongoCommandException:命令getMore失败:找不到游标id xxxxxxxxxx。"我正在使用最新的C#驱动程序(2.6.1)
var agg = collection.Aggregate()
.Group(new BsonDocument
{
{ "_id" , "$FileID" },
{ "id", new BsonDocument
{
{ "$min", "$_id" }
}
},
{ "Count", new BsonDocument
{
{"$sum", 1 }
} }
})
.Match(new BsonDocument
{ { "Count", new BsonDocument { { "$gt", 1 } } }
});
agg.Options.AllowDiskUse = true;
var results = agg.ToEnumerable();
var deletedCount = 0;
// exception occurs here
foreach (var result in results)
{
collection.DeleteOne(x => x.Id == result["id"].AsObjectId);
deletedCount += 1;
Console.WriteLine("Deleted Count: " + deletedCount);
}
我研究了这个问题,听起来问题是光标超时了,但我尝试删除光标超时没有运气。我能够解决这个问题的唯一方法是使用ToList(),它将整个结果加载到我不想对这些大查询做的内存中。
任何帮助都会受到赞赏,我已经花了很多时间来对付这个,几乎没有结果。
答案 0 :(得分:1)
这实际上使我想起了我曾经使用服务器端游标遇到的一个问题,这里很可能是一个类似的问题。您正在修改(.DeleteOne
...)您要迭代的集合。就我而言,我有一个简单的查询,即要进行迭代,然后在该循环中,我会将文档插入到MongoDB中,该文档将被游标拾取。那给了我一个无尽的循环...
现在,您要删除此处的内容,但是,我想这可能仍会引起一些时髦的行为。也许是一种选择
a)尝试为.Delete()
使用单独的MongoDB客户端?我怀疑这是否有帮助,但值得一试
b)在继续进行批量删除(ObjectId
)之前,不要简单地保留好好几千万个DeleteMany()
的列表,而不是直接删除它,这与删除单个对象相比可能会加快处理速度文件?