Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何从每个回调中取消MongoDB查询_Node.js_Mongodb - Fatal编程技术网

Node.js 如何从每个回调中取消MongoDB查询

Node.js 如何从每个回调中取消MongoDB查询,node.js,mongodb,Node.js,Mongodb,我实现了一个小型NodeJs web服务器,它存储日志条目并为基于web的日志浏览器提供后端。web界面还提供了导出到CVS的功能,并允许用户下载CVS格式的日志。我的代码与此类似: this.log_entries(function(err, collection) { collection.find(query) .sort({_id: 1}) .each(function (err, doc) { if(doc){

我实现了一个小型NodeJs web服务器,它存储日志条目并为基于web的日志浏览器提供后端。web界面还提供了导出到CVS的功能,并允许用户下载CVS格式的日志。我的代码与此类似:

this.log_entries(function(err, collection) {
    collection.find(query)
        .sort({_id: 1})
        .each(function (err, doc) {
            if(doc){
              WriteLineToCSVFile(doc);
            }
            else {
              ZipCSVFileAndSendIt();
            }
        });
});
如果用户没有为查询指定正确的筛选器,则导出操作可能会占用大量时间和磁盘空间。我需要实现一个故障安全机制来防止这种情况。一个重要的要求是,用户应该能够在任何时间点中止正在进行的导出操作。目前我的解决方案是,我停止将数据写入CSV文件,但是回调传递给。每个仍会被调用。我找不到任何关于如何停止每个循环的信息。所以问题是我该怎么做

更新,答案是: 使用cursor.nextObject 有关正确答案,请参见下面@dbra的评论:db.currentOp和db.killOp不适用于这种情况

最终的解决方案如下所示:

this.log_entries(function(err, collection) {
    var cursor = collection.find(query);
    cursor.sort("_id", 1, function(err, sorted) {

        function exportFinished(aborted) {
            ...
        }

        function processItem(err, doc) {
            if(doc === null ) {
                exportFinished(false);
            }
            else if( abortCurrentExport ) {
                exportFinished(true);
            }
            else {
                var line = formatCSV(doc);
                WriteFile(line);
                process.nextTick(function(){
                    sorted.nextObject(processItem);
                });
            }
        }
        sorted.nextObject(processItem);
    });
});

注意process.nextTick的用法-如果没有它,将出现堆栈溢出

您可以使用搜索正在运行的查询,然后使用终止查询,但il将是一个令人讨厌的解决方案


一个更好的方法是处理有限的后续批次;更简单的方法是使用limit和skip进行简单的分页,但这取决于您在读取集合时如何更改。

奇怪的是,db.currentOp没有显示任何正在运行的内容。可能是因为查询本身没有运行,只是光标,但可能是我错了。关于限制和跳过-我认为这会减慢速度,因为这些操作非常慢。如果分页不适用,并且操作没有显示,那么看起来只是获取的问题,因此,您可以通过在cursor.next上循环来切换到迭代方法,而不是使用批量函数forEach:然后您可以随时停止抓取循环。您还可以调整传输的块大小cursor.batchSize.Thank@dbra!使用cursor.nextObject是个好主意。现在一切正常!