简体   繁体   English

MongoDB NodeJS本机游标过早关闭

[英]MongoDB NodeJS Native cursor closing prematurely

I'm executing a process to each element of a ursor, my collection has around 6 million documents, the entire process would take up to 10 hours since I have to process a profile at a time and it's a somewhat complex process for each one.我正在对 ursor 的每个元素执行一个过程,我的集合有大约 600 万个文档,整个过程最多需要 10 个小时,因为我必须一次处理一个配置文件,而且每个过程都有些复杂。

 var cursor = dbMain.collection("profiles").find({});

 var getNext = function(){
      cursor.nextObject(processOne);
 };

 var processOne = function(err, profile){
      if(err){
           console.error("Error loading profile", err);
           getNext();
      } else if(profile == null){
           // process is done, all profiles processed!!!
      } else {
           processProfile(profile)
               .then(function(){
                    getNext();
               })
               .catch(function(errProfile){
                    console.error("Error processing profile", errProfile);
                    getNext();
               });
      }
 };

 var processProfile = function(profile){
      // Complex profile processing and promise resolve when done
 };

 getNext();

PROBLEM: I get null (which would mean the cursor has been exhausted) when i'm around 300,000 profiles, so, only the first 300,000 or so get processed.问题:当我有大约 300,000 个配置文件时,我得到 null(这意味着光标已用尽),因此,只有前 300,000 个左右得到处理。 ¿Anyone knows how to deal with it or the reason I'm getting null way before time? ¿有人知道如何处理它或我在时间之前变得无效的原因吗?

It seems I've found the reason:看来我找到了原因:

Since it's a cursor that needs to be alive a long time, in the find options I had to add "timeout : false".由于它是一个需要长时间存活的游标,因此在查找选项中我必须添加“超时:假”。

 var cursor = dbMain.collection("profiles").find({}, {timeout : false});

In the driver documentation says it's false by default (well it's not!!) , now all of my profiles get processed.驱动程序文档中说默认情况下它是假的(好吧,它不是!!),现在我的所有配置文件都得到处理。

For anyone who stumbles upon this one on latest MongoDB drivers, be aware of the following.对于在最新的 MongoDB 驱动程序上偶然发现此驱动程序的任何人,请注意以下内容。 If you call .hasNext() twice after the last .next() call, you will get: Error: Cursor is closed .如果在最后一次.next()调用后调用.hasNext()两次,您将得到: Error: Cursor is closed

For example:例如:

while(await cursor.hasNext()) {
    await cursor.next();
}

if (await cursor.hasNext()) {} // Error!

if (!cursor.isClosed() && await cursor.hasNext()) {} // Correct way

I had the same issue, i resolved it by pushing each document of the cursor on a list and then returning the list, as shown here:我遇到了同样的问题,我通过将光标的每个文档推送到列表上然后返回列表来解决它,如下所示:

const list:any= [];
const cursor= await client.db('insertYourDb').collection('insertYourCollection').find().forEach(function(document) { 
        list.push(document) 
    });
return list;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM