NodeJS MongoDB 避免了游标超时



我想循环抛出MongoDB特定集合上的所有文档。但是,由于光标超时,我所做的每次尝试都失败了。这是我的代码

let MongoClient = require('mongodb').MongoClient;
const url = "my connection URI"
let options = { socketTimeoutMS: 120000, connectTimeoutMS: 120000, keepAlive: 100, poolSize: 5 }
MongoClient.connect(url, options,
function(err, db) {
if (err) throw err
let dbo = db.db("notes")
let collection = dbo.collection("stats-network-consumption")
let stream = collection.find({}, { timeout: false }).stream()
stream.on("data", function(item) {
printTask(item)
})
stream.on('error', function (err) {
console.error(err)
})
stream.on("end", function() {
console.log("DONE!")
db.close()
})
})

上面的代码运行大约 15 秒,检索 6000 到 8000 个文档,然后抛出以下错误:

{ MongoError: cursor does not exist, was killed or timed out
at queryCallback (/Volumes/safezone/development/workspace-router/migration/node_modules/mongodb-core/lib/wireprotocol/2_6_support.js:136:23)
at /Volumes/safezone/development/workspace-router/migration/node_modules/mongodb-core/lib/connection/pool.js:541:18
at process._tickCallback (internal/process/next_tick.js:150:11)
name: 'MongoError',
message: 'cursor does not exist, was killed or timed out' }

我需要检索大约 50000 个文档,所以我需要找到一种方法来避免光标超时。

如上面的代码所示,我尝试增加socketTimeoutMSconnectTimeoutMS,这对光标超时没有影响。

我还尝试用forEach替换stream并添加.addCursorFlag('noCursorTimeout', true),但也没有帮助。

我已经尝试了我发现的关于mongodb的所有内容,我没有尝试猫鼬或替代品,因为它们使用模式,稍后我必须更新属性的当前类型(这对于猫鼬模式来说可能很棘手)。

通常不建议使用没有超时的游标。

原因是,服务器永远不会关闭光标,因此,如果您的应用程序崩溃并且您重新启动它,它将在服务器上打开另一个无超时光标。经常回收您的应用程序,这些会加起来。

分片集群上没有超时游标也会阻止块迁移。

如果需要检索大结果,则游标不应超时,因为结果将分批发送,并且游标将重用以获取下一批。

标准游标超时为 10 分钟,因此如果需要超过 10 分钟来处理批处理,则可能会丢失游标。

在您的代码示例中,您使用stream()可能会干扰您的意图。尝试在光标上使用each()(此处的示例)。

如果您需要监视集合的更改,您可能需要查看 Change Streams,这是 MongoDB 3.6 中的一个新功能。

例如,可以按以下方式修改代码:

let collection = dbo.collection("stats-network-consumption")
let stream = collection.watch()
document = next(stream)

请注意,若要启用更改流支持,所使用的驱动程序必须支持 MongoDB 3.6 功能和watch()方法。有关详细信息,请参阅驱动程序兼容性页面。

相关内容

  • 没有找到相关文章

最新更新