Node.js reuse MongoDB reference

前端 未结 3 1742
萌比男神i
萌比男神i 2021-01-31 11:35

I am having trouble understanding node.js.

Example, MongoDB access, here\'s what I\'ve got (mydb.js):

var mongodb = require(\'mongodb\'),
    server = ne         


        
3条回答
  •  囚心锁ツ
    2021-01-31 11:54

    mydb.js:

    var mongodb= require('mongodb'),
      server = new mongodb.Server('staff.mongohq.com', 10030, {
        auto_reconnect: true
      }),
      db1 = new mongodb.Db('mydb', server);
    
    
    // callback: (err, db)
    function openDatabase(callback) {
      db1.open(function(err, db) {
        if (err)
          return callback(err);
    
        console.log('Database connected');
    
        return callback(null, db);
      });
    }
    
    // callback: (err, collection)
    function authenticate(db, username, password, callback) {
      db.authenticate(username, password, function(err, result) {
        if (err) {
          return callback (err);
        }
        if (result) {
          var collection = new mongodb.Collection(db, 'test');
    
          // always, ALWAYS return the error object as the first argument of a callback
          return callback(null, collection);
        } else {
          return callback (new Error('authentication failed'));
        }
      });
    }
    
    exports.openDatabase = openDatabase;
    exports.authenticate = authenticate;
    

    use.js:

    var mydb = require('./mydb');
    // open the database once
    mydb.openDatabase(function(err, db) {
      if (err) {
        console.log('ERROR CONNECTING TO DATABASE');
        console.log(err);
        process.exit(1);
      }
    
      // authenticate once after you opened the database. What's the point of 
      // authenticating on-demand (for each query)?
      mydb.authenticate(db, 'usernsame', 'password', function(err, collection) {
        if (err) {
          console.log('ERROR AUTHENTICATING');
          console.log(err);
          process.exit(1);
        }
    
        // use the returned collection as many times as you like INSIDE THE CALLBACK
        collection.find({}, {limit: 10})
        .toArray(function(err, docs) {
          console.log('\n------ 1 ------');
          console.log(docs);
        });
    
        collection.find({}, {limit: 10})
        .toArray(function(err, docs) {
          console.log('\n------ 2 ------');
          console.log(docs);
        });
      });
    });
    

    Result:

    on success:

     Database connected
     Database user authenticated
    
    ------ 1 ------
    [ { _id: 4f86889079a120bf04e48550, asd: 'asd' } ]
    
    ------ 2 ------
    [ { _id: 4f86889079a120bf04e48550, asd: 'asd' } ]
    

    on failure:

    Database connected
    { [MongoError: auth fails] name: 'MongoError', errmsg: 'auth fails', ok: 0 }
    

    [Original Answer]:

    You're opening the db multiple times (once in each query). You should open the database just once, and use the db object in the callback for later use.

    You're using the same variable name multiple times, and that might've caused some confusion.

    var mongodb = require('mongodb'),
        server = new mongodb.Server('staff.mongohq.com', 10030, {
            auto_reconnect: true
        }),
        db1 = new mongodb.Db('mydb', server);
    
    function authenticateAndGo(db, handle) {
        db.authenticate('username', 'password', function(err) {
            if (err) {
                console.log(err);
                return;
            }
            console.log('Database user authenticated');
    
            var collection = new mongodb.Collection(db, 'test');
    
            handle(collection);
        });
    }
    
    function query(handle) {
        db1.open(function(err, db2) {
            if( err ) {
                console.log(err);
                return;
            }
            console.log('Database connected');
    
            authenticateAndGo(db2, handle);
        });
    };
    exports.query = query;
    

    I've changed the above code a little (db1 for the original db, db2 for the opened db). As you can see, you're opening db1 multiple times, which is not good. extract the code for opening into another method and use it ONCE and use the db2 instance for all your queries/updates/removes/...

提交回复
热议问题