原因有人已经讲得很清楚了:
你在用 db.collection.find() 的时候,它返回的不是所有的数据,而实际上是一个“cursor”。它的默认行为是:第一次向数据库查询 101 个文档,或 1 MB 的文档,取决于哪个条件先满足;之后每次cursor 中的文档用尽后,查询 4 MB 的文档。另外,find() 的默认行为是返回一个 10 分钟无操作后超时的 cursor。如果我一个 batch 的文档十分钟内没处理完,过后再处理完了,再用同一个 cursor id 向服务器取下一个 batch,这时候cursor id 当然已经过期了,这也就能解释为啥我得到 cursor id 无效的错误了。
解决办法是估计一个 batch 大小,让 MongoDB 客户端每次抓取的文档在 10 分钟内能用完,这样客户端就不得不 10 分钟内至少联系服务器一次,保证cursor 不超时。
修改后代码:
MongoDBClient mongodb = new MongoDBClient(ip, port)