MongoError:连接在MongoDB驱动程序中由应用程序关闭

时间:2015-08-15 08:40:18

标签: node.js mongodb

在NodeJS中运行以下代码时,我收到错误 MongoError:应用程序已关闭连接。我试图解决它但无法一直无法解决。我需要别人的帮助......

var MongoClient = require('mongodb').MongoClient;

MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
    if(err) throw err;

    var data = db.collection('data');
    var options = { 'sort' : [['State', 1], ['Temperature', -1]] };
    var cursor = data.find({}, {}, options);

    var firstState = '';
    var currentState='';
    var previousState='';
    var previousRecord='';

    cursor.each(function(err, doc) {
        if(err) throw err;
        if(doc == null) {
            return db.close();
        }

        currentState= doc['State'];
        previousState = previousRecord['State'];

        if(previousState === undefined) {           
            console.dir(currentState);
            firstState= doc['State'];

            db.collection('data').update({'_id' : doc['_id']}, {$set :{'month_high' : true}}, {'upsert' : true}, function(err, upserted){
                if(err) throw err;

                console.dir("Successfully upserted "+upserted + " document!");
            });

        } else if(currentState !=previousState){
                if (firstState!=currentState){                
                    console.dir(previousState);

                db.collection('data').update({'_id' : previousRecord['_id']}, {$set :{'month_high' : true}}, {'upsert' : true}, function(err, upserted){
                if(err) throw err;               

                console.dir("Successfully upserted "+upserted + " document!");
            });

                }
            }        

        previousRecord = doc;
    });
});

2 个答案:

答案 0 :(得分:1)

这是异步调用数据库的异步代码,但此处使用的[root@mongo wok]# cd node_modules/ [root@mongo node_modules]# ls socket.io [root@mongo node_modules]# cd socket.io/ [root@mongo socket.io]# ls History.md index.js lib LICENSE Makefile node_modules package.json Readme.md [root@mongo socket.io]# ls -al total 68 drwxr-xr-x 4 root root 4096 Aug 15 01:50 . drwxr-xr-x 3 root root 4096 Aug 15 01:50 .. -rw-r--r-- 1 root root 15740 Jul 14 17:36 History.md -rw-r--r-- 1 root root 36 Jul 8 09:29 index.js drwxr-xr-x 2 root root 4096 Aug 15 01:50 lib -rw-r--r-- 1 root root 1096 May 25 14:29 LICENSE -rw-r--r-- 1 root root 235 May 25 14:29 Makefile drwxr-xr-x 8 root root 4096 Aug 15 01:50 node_modules -rw-r--r-- 1 root root 33 May 25 14:29 .npmignore -rw-r--r-- 1 root root 1932 Aug 15 01:50 package.json -rw-r--r-- 1 root root 10380 Jul 8 09:29 Readme.md -rw-r--r-- 1 root root 197 Jul 8 09:29 .travis.yml [root@mongo socket.io]# cat package.json { "name": "socket.io", "version": "1.3.6", "description": "node.js realtime framework server", "keywords": [ "realtime", "framework", "websocket", "tcp", "events", "socket", "io" ], "repository": { "type": "git", "url": "git://github.com/Automattic/socket.io.git" }, "scripts": { "test": "mocha --reporter dot --slow 200ms --bail" }, 迭代器不会等待包含的回调完成。

这是此处出错的主要原因,因为在调用.each()时处理尚未实际完成。所以这就是需要解决的问题。

虽然对代码的一般清理肯定是有序的,但这里的主要内容是用stream processing替换该循环,并且通过仅改变条件避免“重复自己”调用“更新”并将流量控制保持在一个地方:

db.close()

var MongoClient = require('mongodb').MongoClient; MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) { if(err) throw err; var data = db.collection('data'); var options = { 'sort' : [['State', 1], ['Temperature', -1]] }; var cursor = data.find({}, {}, options); var firstState = '', currentState='', previousState='', previousRecord=''; cursor.on("end",function() { db.close(); }); cursor.on("err",function(err) { throw err; }); cursor.on("data",function(data){ cursor.pause(); // Stops events emitting on stream currentState = doc.State; previousState = previousRecord.State; var query = { "_id": null }; if (previousState === undefined) { console.dir(currentState); firstState= doc.State; query._id = doc._id; } else if(currentState != previousState) { if (firstState != currentState) { console.dir(previousState); query._id = previousRecord._id; } } if (query._id != null) { db.collection('data').update( query, { "$set":{ "month_high": true } }, { "upsert": true }, function(err, upserted){ if(err) throw err; console.dir("Successfully upserted "+upserted + " document!"); cursor.resume(); // resumes events on stream previousRecord = doc; }); } else { cursor.resume(); // resumes events on stream previousRecord = doc; } }); }); .pause()方法确保在检索当前文档的当前处理完成之前,流中不会发出新数据。这样可以检查外部变量。

请注意,.resume()也会在.resume()的回调中“调用”,因为您不想继续此操作,直到返回完成为止。

答案 1 :(得分:0)

我重写了实施 node stream 界面的应用程序,该界面最终解决了" MongoError:连接已被应用程序关闭" 的问题。

var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {   
     if(err) throw err;
     var data = db.collection('data');
     var options = { 'sort' : [['State', 1], ['Temperature', -1]] };
     var cursor = data.find({}, {}, options);

     var previousState='';  

    cursor.on("end", function(){
        db.close();
    });

    cursor.on("err", function(){
        console.dir("Error on:" + err);
        throw err;
    });

cursor.on("data", function(doc){
    cursor.pause();
    if(previousState != doc.State){
        previousState = doc.State;
        var query = { _id: doc._id};
        var operator = {$set: {month_high: true}};

        db.collection('data').update(query, operator, {'upsert' : true}, function(err, upserted){
          if(err){
                console.dir('Error : '+ err);
                throw err;
            } 
            console.dir("Successfully upserted "+ upserted + " document!");
            cursor.resume();
        });
    } else{
            cursor.resume();
    }
});

});