【问题标题】:MongoDB NodeJS driver, how to know when .update() 's are completeMongoDB NodeJS 驱动程序,如何知道 .updates 何时完成
【发布时间】:2015-09-03 06:47:36
【问题描述】:

由于这里发布的代码相当大,我附上了我的 github repo https://github.com/DiegoGallegos4/Mongo

我正在尝试使用 de NodeJS 驱动程序来更新一些满足某个条件的记录,但首先我必须找到一些满足另一个条件的记录。在更新部分,使用从查找操作中找到的记录和过滤器。这是,

文件:weather1.js

MongoClient.connect(some url, function(err,db){
    db.collection(collection_name).find({},{},sort criteria).toArray(){
          .... find the data and append to an array
          .... this data inside a for loop
          db.collection(collection_name).update(data[i], {$set...}, callback)
    }
})

这是用于解决问题的结构,与何时关闭连接有关,即数据数组的长度等于更新操作的回调次数。有关更多详细信息,您可以参考 repo。

文件:weather.js

在另一种方法中,使用 .each 代替 toArray 来迭代光标。

我已经在几个论坛上寻找了一个星期的解决方案。

我已阅读有关池连接的信息,但我想知道我的代码中的概念错误是什么。我希望能深入了解这个主题。

【问题讨论】:

    标签: node.js mongodb mongodb-query node-mongodb-native


    【解决方案1】:

    您提出问题的方式非常具有误导性。您只想知道“什么时候处理完毕,我可以关闭?”

    答案是您需要尊重回调,通常只有在每次更新完成后才会在结果的光标中移动。

    没有其他依赖的简单方法是使用驱动支持的stream interface

    var MongoClient = require('mongodb').MongoClient;
    
    MongoClient.connect('mongodb://localhost:27017/data',function(err,db){
    
        if(err) throw err;
    
        coll = db.collection('weather');
        console.log('connection established')
    
        var stream = coll.find().sort([['State',1],['Temperature',-1]])
    
        stream.on('err',function(err) {
            throw err;
        });
    
        stream.on('end',function() {
            db.close();
        });
    
        var month_highs = [];
        var state = '';
        var length = 0;
    
    
        stream.on('data',function(doc) { 
            stream.pause();                           // pause processing documents
    
            if (err) throw err;
    
            if (doc) {
                length = month_highs.length
                if(state != doc['State']){
                    month_highs.push(doc['State']);
                    //console.log(doc);
                }
                state = doc['State']
    
                if(month_highs.length > length){
                    coll.update(doc, {$set : {'month_high':true} }, function(err, updated){
                        if (err) throw err;
                        console.log(updated)
                        stream.resume();              // resume processing documents
                    });
                } else {
                    stream.resume();
                }
            } else {
                stream.resume();
            }
        });
    
    });
    

    这只是您存储库中代码的副本,已重构为使用流。所以所有重要的部分都是“流”这个词出现的地方,最重要的是它们被调用的地方。

    简而言之,每个文档从游标结果中发出“数据”事件。首先,您调用.pause(),这样新文档就不会超出处理范围。然后你执行你的.update() 并在它的回调中调用.resume(),然后流程继续下一个文档。

    当光标耗尽时,最终会发出“end”,这就是你调用db.close()的地方。

    这是基本的流量控制。对于其他方法,请查看 node async 库作为一个好帮手。但不要循环没有异步控制的数组,也不要使用 已弃用.each()

    您需要在.update() 回调完成时发出信号,以无论如何都要遵循新的“循环迭代”。这是基本的无附加依赖方法。

    P.S 我有点怀疑你的代码的一般逻辑,特别是在你阅读它而不可能改变该长度的情况下测试它的长度是否更大。但这都是关于如何实现“流控制”,而不是修复代码中的逻辑。

    【讨论】:

    • 如何改进测试逻辑?每次将新项目添加到数组中时,我都想添加该项目,这就是我的陈述方式。看看上面github.com/DiegoGallegos4/Mongo/blob/master/error.rtf的代码抛出的这个错误。如果可以帮助您,我的 mongo 版本是 3.0.5。
    • @DiegoGallegos 真的不确定你在这里真正想要做什么,所以也许你应该在另一个问题中完全问这个问题。您在这里的问题基本上是关于“流量控制”和每次更新和所有更新完成时的信号(尽管您可能对此有更多的了解)。如果您还有其他问题,那么Ask A new Question。我们只能真正回答所提出的问题,将您的“问题”分开会更清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    相关资源
    最近更新 更多