我正在使用本机Node JS驱动程序(3.0.10版)在Mongo 3.6.6(小型Mongo Atlas群集,未分片)上运行
我的代码如下:
const records = await collection.find({
userId: ObjectId(userId),
status: 'completed',
lastUpdated: {
$exists: true,
$gte: '2018-06-10T21:24:12.000Z'
}
}).toArray();
我偶尔会看到此错误:
{
"name": "MongoError",
"message": "cursor id 16621292331349 not found",
"ok": 0,
"errmsg": "cursor id 16621292331349 not found",
"code": 43,
"codeName": "CursorNotFound",
"operationTime": "6581469650867978275",
"$clusterTime": {
"clusterTime": "6581469650867978275",
"signature": {
"hash": "aWuGeAxOib4XWr1AOoowQL8yBmQ=",
"keyId": "6547661618229018626"
}
}
}
对于最多返回几百条记录的查询,就是这种情况。每个记录有几百个字节。
我在网上寻找问题的根源,但是most中的what我found谈论的是非常大的操作的游标超时,这些操作需要超过10分钟才能完成。我无法确切知道失败的查询从我的日志中花费了多长时间,但这最多是两秒钟(可能比这短得多)。
我测试了使用与错误出出的值相同的值运行查询,并且从explain
开始的执行时间只有几毫秒:
"executionStats" : {
"executionSuccess" : true,
"nReturned" : NumberInt(248),
"executionTimeMillis" : NumberInt(3),
"totalKeysExamined" : NumberInt(741),
"totalDocsExamined" : NumberInt(741),
"executionStages" : {...}
},
"allPlansExecution" : []
]
}
有什么想法吗?间歇性网络延迟会导致此错误吗?我将如何缓解呢?谢谢
答案 0 :(得分:2)
您可以尝试以下三件事:
db.collection.find().noCursorTimeout();
您必须使用cursor.close()在某个点关闭光标
db.inventory.find().batchSize(10);
c)光标过期后重试:
let processed = 0;
let updated = 0;
while(true) {
const cursor = db.snapshots.find().sort({ _id: 1 }).skip(processed);
try {
while (cursor.hasNext()) {
const doc = cursor.next();
++processed;
if (doc.stream && doc.roundedDate && !doc.sid) {
db.snapshots.update({
_id: doc._id
}, { $set: {
sid: `${ doc.stream.valueOf() }-${ doc.roundedDate }`
}});
++updated;
}
}
break; // Done processing all, exit outer loop
} catch (err) {
if (err.code !== 43) {
// Something else than a timeout went wrong. Abort loop.
throw err;
}
}
}
答案 1 :(得分:1)
首先,如果您的数据太大,使用toArray()方法不是一个好主意,相反,最好使用forEach()并循环抛出数据。 就是这样:
const records = await collection.find({
userId: ObjectId(userId),
status: 'completed',
lastUpdated: {
$exists: true,
$gte: '2018-06-10T21:24:12.000Z'
}
});
records.forEach((record) => {
//do somthing ...
});
第二,您可以使用{allowDiskUse:true}选项获取大数据。
const records = await collection.find({
userId: ObjectId(userId),
status: 'completed',
lastUpdated: {
$exists: true,
$gte: '2018-06-10T21:24:12.000Z'
}
},
{allowDiskUse: true});