복붙노트

[MONGODB] 때 Nodejs에서 MongoDB를 데이터베이스 연결을 닫습니다

MONGODB

때 Nodejs에서 MongoDB를 데이터베이스 연결을 닫습니다

노드 MongoDB를 기본 드라이버를 통해 NodeJS와 MongoDB를 사용하여 작업. 필요는 일부 문서를 검색하고, 메이크업 수정 후 바로 다시 저장할 수 있습니다. 이 예입니다 :

db.open(function (err, db) {
  db.collection('foo', function (err, collection) {
    var cursor = collection.find({});
    cursor.each(function (err, doc) {
      if (doc != null) {
        doc.newkey = 'foo'; // Make some changes
        db.save(doc); // Update the document
      } else {
        db.close(); // Closing the connection
      }
    });
  });
});

문서를 업데이트하는 프로세스는 커서가 문서의 끝에 도달 한 후 때, 더 이상 걸리는 경우 비동기 자연과, 데이터베이스 연결이 닫힙니다. 모든 업데이트는 데이터베이스에 저장되는 것은 아닙니다.

db.close ()가 생략되면, 모든 문서는 제대로 업데이트되지만 응용 프로그램 중단, 결코 종료됩니다.

나는 가까운 다음, 다시 0 dB 하강 할 때 업데이트의 수를 추적하는 카운터를 사용하여 제안 게시물을 보았다. 하지만 여기에 아무것도 잘못을하고있는 중이 야? 이런 상황을 처리하는 가장 좋은 방법은 무엇입니까? db.close는 () 자원을 확보하기 위해 사용할 수 있습니까? 아니면 새로운 DB 연결 요구를 열 수 있습니까?

해결법

  1. ==============================

    1.다음은 계산 방법에 따라 잠재적 인 솔루션이다 (나는 그것을 테스트하지 않은 오류 트래핑이 없다,하지만 생각을 전달해야한다).

    다음은 계산 방법에 따라 잠재적 인 솔루션이다 (나는 그것을 테스트하지 않은 오류 트래핑이 없다,하지만 생각을 전달해야한다).

    기본 전략은 다음과 같습니다 카운트 (시 마지막 업데이트 완료) 0에 도달하면 비동기 적으로 각 레코드 저장, 업데이트 할 필요가 얼마나 많은 레코드의 수와 수를 감소시킵니다 성공 콜백과 가까운 DB를 취득. {안전 : 사실}를 사용함으로써 우리는 각 업데이트가 성공적으로 보장 할 수 있습니다.

    몽고 서버는의 중 하나에 좋은) 가까운 않는 연결, 또는 b) 수영장 있도록 / 재사용, 연결 당 하나 개의 스레드를 사용합니다.

    db.open(function (err, db) {
      db.collection('foo', function (err, collection) {
        var cursor = collection.find({});
        cursor.count(function(err,count)){
          var savesPending = count;
    
          if(count == 0){
            db.close();
            return;
          }
    
          var saveFinished = function(){
            savesPending--;
            if(savesPending == 0){
              db.close();
            }
          }
    
          cursor.each(function (err, doc) {
            if (doc != null) {
              doc.newkey = 'foo'; // Make some changes
              db.save(doc, {safe:true}, saveFinished);
            }
          });
        })
      });
    });
    
  2. ==============================

    2.이 응용 프로그램의 수명이 다 정리 기능에 풀 된 접속 한 후 호출 db.close ()를 사용하는 것이 가장 좋습니다 :

    이 응용 프로그램의 수명이 다 정리 기능에 풀 된 접속 한 후 호출 db.close ()를 사용하는 것이 가장 좋습니다 :

    process.on('SIGINT', cleanup);
    process.on('SIGTERM', cleanup);
    

    http://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html 참조

    A는 기존 스레드 비트, 어쨌든.

  3. ==============================

    3.나는 카운터를 사용하여 간단한 시나리오에 적용 할 수 있지만, 복잡한 상황에서 어려울 수 있다는 것을 발견했다. 여기에 내가 데이터베이스 연결이 유휴 상태 일 때 데이터베이스 연결을 닫아 마련하는 솔루션입니다 :

    나는 카운터를 사용하여 간단한 시나리오에 적용 할 수 있지만, 복잡한 상황에서 어려울 수 있다는 것을 발견했다. 여기에 내가 데이터베이스 연결이 유휴 상태 일 때 데이터베이스 연결을 닫아 마련하는 솔루션입니다 :

    var dbQueryCounter = 0;
    var maxDbIdleTime = 5000; //maximum db idle time
    
    var closeIdleDb = function(connection){
      var previousCounter = 0;
      var checker = setInterval(function(){
        if (previousCounter == dbQueryCounter && dbQueryCounter != 0) {
            connection.close();
            clearInterval(closeIdleDb);
        } else {
            previousCounter = dbQueryCounter;
        }
      }, maxDbIdleTime);
    };
    
    MongoClient.connect("mongodb://127.0.0.1:27017/testdb", function(err, connection)(
      if (err) throw err;
      connection.collection("mycollection").find({'a':{'$gt':1}}).toArray(function(err, docs) {
        dbQueryCounter ++;
      });   
      //do any db query, and increase the dbQueryCounter
      closeIdleDb(connection);
    ));
    

    이 모든 데이터베이스 연결에 대한 일반적인 해결책이 될 수 있습니다. maxDbIdleTime은 DB 쿼리 제한 시간 이상과 같은 값으로 설정할 수 있습니다.

    이것은 매우 우아하지 않습니다,하지만 난이 할 수있는 더 좋은 방법을 생각할 수 없다. 나는 데이터베이스 연결이 제대로 닫혀 있지 않은 경우 영원히 MongoDB를하고 MySQL을, 그리고 스크립트 중단을 조회하는 스크립트를 실행 NodeJs를 사용합니다.

  4. ==============================

    4.@mpobrien 위의 제안을 바탕으로, 나는 비동기 모듈은이 점에서 매우 도움이 될 것으로 나타났습니다. 저는 여기에 채택 왔어요 예를 들어 패턴입니다 :

    @mpobrien 위의 제안을 바탕으로, 나는 비동기 모듈은이 점에서 매우 도움이 될 것으로 나타났습니다. 저는 여기에 채택 왔어요 예를 들어 패턴입니다 :

    const assert = require('assert');
    const async = require('async');
    const MongoClient = require('mongodb').MongoClient;
    
    var mongodb;
    
    async.series(
        [
            // Establish Covalent Analytics MongoDB connection
            (callback) => {
                MongoClient.connect('mongodb://localhost:27017/test', (err, db) => {
                    assert.equal(err, null);
                    mongodb = db;
                    callback(null);
                });
            },
            // Insert some documents
            (callback) => {
                mongodb.collection('sandbox').insertMany(
                    [{a : 1}, {a : 2}, {a : 3}],
                    (err) => {
                        assert.equal(err, null);
                        callback(null);
                    }
                )
            },
            // Find some documents
            (callback) => {
                mongodb.collection('sandbox').find({}).toArray(function(err, docs) {
                    assert.equal(err, null);
                    console.dir(docs);
                    callback(null);
                });
            }
        ],
        () => {
            mongodb.close();
        }
    );
    
  5. ==============================

    5.여기에 내가 생각 해낸 해결책이다. 그것은 toArray를 사용하여 방지하고 꽤 짧고 달콤한 :

    여기에 내가 생각 해낸 해결책이다. 그것은 toArray를 사용하여 방지하고 꽤 짧고 달콤한 :

    var MongoClient = require('mongodb').MongoClient;
    
    MongoClient.connect("mongodb://localhost:27017/mydb", function(err, db) {
      let myCollection = db.collection('myCollection');
      let query = {}; // fill in your query here
      let i = 0;
      myCollection.count(query, (err, count) => { 
        myCollection.find(query).forEach((doc) => {
          // do stuff here
          if (++i == count) db.close();
        });
      });
    });
    
  6. ==============================

    6.이 같은 카운터를 포함하는 솔루션을 함께했다. 이 카운트 () 호출에 의존하지 않는 않으며 타임 아웃 대기 않습니다. 그것은 소진 각각의 모든 문서 () 후 DB를 닫습니다.

    이 같은 카운터를 포함하는 솔루션을 함께했다. 이 카운트 () 호출에 의존하지 않는 않으며 타임 아웃 대기 않습니다. 그것은 소진 각각의 모든 문서 () 후 DB를 닫습니다.

    var mydb = {}; // initialize the helper object.
    
    mydb.cnt = {}; // init counter to permit multiple db objects.
    
    mydb.open = function(db) // call open to inc the counter.
    {
      if( !mydb.cnt[db.tag] ) mydb.cnt[db.tag] = 1;
      else mydb.cnt[db.tag]++;
    }; 
    
    mydb.close = function(db) // close the db when the cnt reaches 0.
    {
      mydb.cnt[db.tag]--;
      if ( mydb.cnt[db.tag] <= 0 ) {
        delete mydb.cnt[db.tag];
        return db.close();
      }
      return null;
    };
    

    그래서 당신은 갈 때마다이 db.each 같은 호출 () 또는 db.save ()는 작업을 완료하고, 폐쇄하면서 DB를 준비하기 위해이 방법을 사용하려면있다.

    OP에서 예 :

    foo = db.collection('foo');
    
    mydb.open(db); // *** Add here to init the counter.**  
    foo.find({},function(err,cursor)
    {
      if( err ) throw err; 
      cursor.each(function (err, doc)
      {
        if( err ) throw err;
        if (doc != null) {
          doc.newkey = 'foo';
          mydb.open(db); // *** Add here to prevent from closing prematurely **
          foo.save(doc, function(err,count) {
            if( err ) throw err;
            mydb.close(db); // *** Add here to close when done. **
          }); 
        } else {
          mydb.close(db); // *** Close like this instead. **
        }
      });
    });
    

    이제,이 mydb.close ()로 이동 각에서 마지막 콜백 두 번째는 각각의 마지막 콜백 전에 mydb.open ()를 통해 수 있다고 가정이이 경우 .... 그래서, 물론, 알려주세요 발행물.

    그래서 : DB를 호출하기 전에 mydb.open (DB)를 넣어 콜백의 반환 시점에서 mydb.close (dB)을 넣어 또는 DB 호출 후 (통화 유형에 따라).

    카운터의이 종류는 DB 객체 내에서 유지되어야하지만 내 현재의 해결 방법이라고 나에게 보인다. 어쩌면 우리는 생성자에 DB를 취하는 새로운 개체를 만들고 더 가까이를 처리하기 위해 MongoDB의 기능을 래핑 할 수있다.

  7. from https://stackoverflow.com/questions/8373905/when-to-close-mongodb-database-connection-in-nodejs by cc-by-sa and MIT license