it-swarm.com.de

Wie kann die Verbindung zu Mongodb über die NodeJs-Anwendung und -Module ordnungsgemäß wiederverwendet werden?

Ich habe gelesen und gelesen und bin immer noch verwirrt, was die beste Möglichkeit ist, dieselbe Datenbankverbindung (MongoDb) über die gesamte NodeJs-App zu teilen. Nach meinem Verständnis sollte die Verbindung beim Start der App geöffnet und zwischen den Modulen wiederverwendet werden. Meine derzeitige Idee ist, dass server.js (Hauptdatei, wo alles beginnt) eine Verbindung zur Datenbank herstellt und Objektvariablen erstellt, die an Module übergeben werden. Nach dem Verbinden wird diese Variable nach Bedarf vom Modulcode verwendet, und diese Verbindung bleibt geöffnet. Z.B.:

    var MongoClient = require('mongodb').MongoClient;
    var mongo = {}; // this is passed to modules and code

    MongoClient.connect("mongodb://localhost:27017/marankings", function(err, db) {
        if (!err) {
            console.log("We are connected");

            // these tables will be passed to modules as part of mongo object
            mongo.dbUsers = db.collection("users");
            mongo.dbDisciplines = db.collection("disciplines");

            console.log("aaa " + users.getAll()); // displays object and this can be used from inside modules

        } else
            console.log(err);
    });

    var users = new(require("./models/user"))(app, mongo);
    console.log("bbb " + users.getAll()); // not connected at the very first time so displays undefined

dann sieht ein anderes Modul models/user so aus:

Users = function(app, mongo) {

Users.prototype.addUser = function() {
    console.log("add user");
}

Users.prototype.getAll = function() {

    return "all users " + mongo.dbUsers;

    }
}

module.exports = Users;

Jetzt habe ich ein schreckliches Gefühl, dass dies falsch ist. Gibt es offensichtliche Probleme mit diesem Ansatz und wenn ja, wie kann ich das besser machen?

66
spirytus

Sie können ein mongoUtil.js-Modul erstellen, das Funktionen zum Verbinden mit Mongo und zum Zurückgeben einer Mongo-Datenbankinstanz enthält:

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

var _db;

module.exports = {

  connectToServer: function( callback ) {
    MongoClient.connect( "mongodb://localhost:27017/marankings", function( err, db ) {
      _db = db;
      return callback( err );
    } );
  },

  getDb: function() {
    return _db;
  }
};

Um es zu verwenden, würden Sie dies in Ihrem app.js tun:

var mongoUtil = require( 'mongoUtil' );

mongoUtil.connectToServer( function( err ) {
  // start the rest of your app here
} );

Und dann, wenn Sie irgendwo Zugang zu Mongo benötigen, können Sie Folgendes tun:

var mongoUtil = require( 'mongoUtil' );
var db = mongoUtil.getDb();

db.collection( 'users' ).find();

Der Grund dafür ist, dass im Knoten, wenn Module require 'd sind, diese nur einmal geladen/beschafft werden, sodass Sie immer nur eine Instanz von _db erhalten und mongoUtil.getDb() immer dieselbe Instanz zurückgibt.

Beachten Sie, der Code wurde nicht getestet.

108
go-oleg

So mache ich es mit zeitgenössischer Syntax, basierend auf dem Beispiel von go-oleg. Meine ist getestet und funktionell.

Ich habe einige Kommentare in den Code eingefügt.

./db/mongodb.js

 const MongoClient = require('mongodb').MongoClient
 const uri = 'mongodb://user:[email protected]:27017/dbName'
 let _db

 const connectDB = async (callback) => {
     try {
         MongoClient.connect(uri, (err, db) => {
             _db = db
             return callback(err)
         })
     } catch (e) {
         throw e
     }
 }

 const getDB = () => _db

 const disconnectDB = () => _db.close()

 module.exports = { connectDB, getDB, disconnectDB }

./index.js

 // Load MongoDB utils
 const MongoDB = require('./db/mongodb')
 // Load queries & mutations
 const Users = require('./users')

 // Improve debugging
 process.on('unhandledRejection', (reason, p) => {
     console.log('Unhandled Rejection at:', p, 'reason:', reason)
 })

 const seedUser = {
     name: 'Bob Alice',
     email: '[email protected]',
     bonusSetting: true
 }

 // Connect to MongoDB and put server instantiation code inside
 // because we start the connection first
 MongoDB.connectDB(async (err) => {
     if (err) throw err
     // Load db & collections
     const db = MongoDB.getDB()
     const users = db.collection('users')

     try {
         // Run some sample operations
         // and pass users collection into models
         const newUser = await Users.createUser(users, seedUser)
         const listUsers = await Users.getUsers(users)
         const findUser = await Users.findUserById(users, newUser._id)

         console.log('CREATE USER')
         console.log(newUser)
         console.log('GET ALL USERS')
         console.log(listUsers)
         console.log('FIND USER')
         console.log(findUser)
     } catch (e) {
         throw e
     }

     const desired = true
     if (desired) {
         // Use disconnectDB for clean driver disconnect
         MongoDB.disconnectDB()
         process.exit(0)
     }
     // Server code anywhere above here inside connectDB()
 })

./users/index.js

 const ObjectID = require('mongodb').ObjectID

 // Notice how the users collection is passed into the models
 const createUser = async (users, user) => {
     try {
         const results = await users.insertOne(user)
         return results.ops[0]
     } catch (e) {
         throw e
     }
 }

 const getUsers = async (users) => {
     try {
         const results = await users.find().toArray()
         return results
     } catch (e) {
         throw e
     }
 }

 const findUserById = async (users, id) => {
     try {
         if (!ObjectID.isValid(id)) throw 'Invalid MongoDB ID.'
         const results = await users.findOne(ObjectID(id))
         return results
     } catch (e) {
         throw e
     }
 }

 // Export garbage as methods on the Users object
 module.exports = { createUser, getUsers, findUserById }
11
agm1984

Wenn Sie Express verwenden, können Sie das Modul express-mongo-db verwenden, mit dem Sie die Db-Verbindung im Anforderungsobjekt abrufen können.

Installieren

npm install --save express-mongo-db

server.js

var app = require('express')();

var expressMongoDb = require('express-mongo-db');
app.use(expressMongoDb('mongodb://localhost/test'));

routes/users.js

app.get('/', function (req, res, next) {
    req.db // => Db object
});
11

go-oleg hat grundsätzlich recht, aber heutzutage willst du (wahrscheinlich) nicht "mongodb" selbst verwenden, sondern ein Framework verwenden, das eine Menge "schmutzige Arbeit" für dich erledigt.

Zum Beispiel ist der Mungo einer der häufigsten. Das haben wir in unserer ursprünglichen server.js-Datei:

const mongoose = require('mongoose');
const options = {server: {socketOptions: {keepAlive: 1}}};
mongoose.connect(config.db, options);

Dies ist alles, was zum Einrichten benötigt wird. Verwenden Sie dies jetzt überall in Ihrem Code

const mongoose = require('mongoose');

Und Sie erhalten die Instanz, die Sie mit mongoose.connect eingerichtet haben.

6
libik

Initialisieren Sie die Verbindung als Versprechen:

const MongoClient = require('mongodb').MongoClient
const uri = 'mongodb://...'
const client = new MongoClient(uri)
const connection = client.connect() // initialized connection

Rufen Sie dann die Verbindung auf, wann immer Sie möchten, dass Sie eine Aktion für die Datenbank ausführen:

    // if I want to insert into the database...
    const connect = connection
    connect.then(() => {
        const doc = { id: 3 }
        const db = client.db('database_name')
        const coll = db.collection('collection_name')
        coll.insertOne(doc, (err, result) => {
            if(err) throw err
        })
    })
3
Henry Bothin

Es gibt viele Möglichkeiten, wie dies optimiert werden kann, um Konfigurationsobjekte an bestimmten Stellen zu akzeptieren. Insgesamt ähnelt es jedoch dem Aufbau Ihres Codes, wenn auch mit einer moderneren JS-Syntax. Könnte leicht in Prototypen und Rückrufe umgeschrieben werden, wenn dies Ihre Anforderung ist.

mongo.js

const { MongoClient } = require('mongodb');
const config = require('./config');
const Users = require('./Users');
const conf = config.get('mongodb');

class MongoBot {
  constructor() {
    const url = `mongodb://${conf.hosts.join(',')}`;

    this.client = new MongoClient(url, conf.opts);
  }
  async init() {
    await this.client.connect();
    console.log('connected');

    this.db = this.client.db(conf.db);
    this.Users = new Users(this.db);
  }
}

module.exports = new MongoBot();

Users.js

class User {
  constructor(db) {
    this.collection = db.collection('users');
  }
  async addUser(user) {
    const newUser = await this.collection.insertOne(user);
    return newUser;
  }
}
module.exports = User;

app.js

const mongo = require('./mongo');

async function start() {
  // other app startup stuff...
  await mongo.init();
  // other app startup stuff...
}
start();

someFile.js

const { Users } = require('./mongo');

async function someFunction(userInfo) {
  const user = await Users.addUser(userInfo);
  return user;
}
3
EddieDean

Wenn Sie sich für die Verwendung von Mungo in Ihrer Anwendung entscheiden, bearbeiten Sie die Datei app.js mit dem folgenden Snippet

app.js

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/Your_Data_Base_Name', {useNewUrlParser:true})
  .then((res) => {
    console.log(' ########### Connected to mongDB ###########');
  })
  .catch((err) => {
    console.log('Error in connecting to mongoDb' + err);
  });`

Nächster Schritt: Definieren Sie Modelle für Ihre Anwendung, und führen Sie die CRUD-Operation beispielsweise direkt aus

blogSchema.js

 const mongoose = require('mongoose');
 const Schema = mongoose.Schema;
 const blogSchema = new Schema({
     _id : mongoose.Schema.Types.ObjectId,
     title : {
        type : 'String',
        unique : true,
        required : true       
    },
    description : String,
        comments : [{type : mongoose.Schema.Types.ObjectId, ref: 'Comment'}]
 });
 module.exports = mongoose.model('Blog', blogSchema);

Verwendung createBlog.js

const Blog = require('../models/blogSchema');
exports.createBlog = (req, res, next) => {
const blog = new Blog({
  _id : new mongoose.Types.ObjectId,
  title : req.body.title,
  description : req.body.description,
});
blog.save((err, blog) => {
  if(err){
    console.log('Server Error save fun failed');
    res.status(500).json({
      msg : "Error occured on server side",
      err : err
    })
  }else{
    //do something....
  }

Sie müssen sich nicht immer mit mogoDB verbinden ...

2
Naresh_Varma
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/';
var Pro1;

module.exports = {
    DBConnection:async function()
    {
        Pro1 = new Promise(async function(resolve,reject){
            MongoClient.connect(url, { useNewUrlParser: true },function(err, db) {
                if (err) throw err;
                resolve(db);
            });        
        });
    },
    getDB:async function(Blockchain , Context)
    {
        bc = Blockchain;
        contx = Context;
        Pro1.then(function(_db)
        {
            var dbo = _db.db('dbname');
            dbo.collection('collectionname').find().limit(1).skip(0).toArray(function(err,result) {
                if (err) throw err;
                console.log(result);
            });
        });
    },
    closeDB:async function()
    {
        Pro1.then(function(_db){
            _db.close();
        });
    }
};
2
Tejas Naik

Eine getestete Lösung basierend auf der akzeptierten Antwort:

mongodbutil.js:

var MongoClient = require( 'mongodb' ).MongoClient;
var _db;
module.exports = {
  connectToServer: function( callback ) {
    MongoClient.connect( "<connection string>", function( err, client ) {
      _db = client.db("<collection name>");
      return callback( err );
    } );
  },
  getDb: function() {
    return _db;
  }
};

app.js:

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

var mongodbutil = require( './mongodbutil' );
mongodbutil.connectToServer( function( err ) {
  //app goes online once this callback occurs
  var indexRouter = require('./routes/index');
  var usersRouter = require('./routes/users');
  var companiesRouter = require('./routes/companies');
  var activitiesRouter = require('./routes/activities');
  var registerRouter = require('./routes/register');  
  app.use('/', indexRouter);
  app.use('/users', usersRouter);
  app.use('/companies', companiesRouter);
  app.use('/activities', activitiesRouter);
  app.use('/register', registerRouter);  
  // catch 404 and forward to error handler
  app.use(function(req, res, next) {
    next(createError(404));
  });
  // error handler
  app.use(function(err, req, res, next) {
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};
    res.status(err.status || 500);
    res.render('error');
  });
  //end of calback
});

module.exports = app;

aktivitäten.js - eine Route:

var express = require('express');
var router = express.Router();
var mongodbutil = require( '../mongodbutil' );
var db = mongodbutil.getDb();

router.get('/', (req, res, next) => {  
    db.collection('activities').find().toArray((err, results) => {
        if (err) return console.log(err)
            res.render('activities', {activities: results, title: "Activities"})
    });
});

router.post('/', (req, res) => {
  db.collection('activities').save(req.body, (err, result) => {
    if (err) return console.log(err)
    res.redirect('/activities')
  })
});

module.exports = router;

1
steve

wir können eine dbconnection-Datei wie dbconnection.js erstellen

const MongoClient = require('mongodb').MongoClient
const mongo_url = process.env.MONGO_URL;

    module.exports = {
        connect: async function(callback) {
            var connection;
            await new Promise((resolve, reject) => {
                MongoClient.connect(mongo_url, {
                    useNewUrlParser: true
                }, (err, database) => {
                    if (err)
                        reject();
                    else {
                        connection = database;
                        resolve();
                    }
                });
            });
            return connection;
        }

    };

und dann diese Datei in Ihrer App verwenden

var connection = require('../dbconnection');

und dann wie folgt in Ihrer Async-Funktion verwenden 

db  = await connection.connect();

hoffe das klappt

0
gaurav

Ich bin ein bisschen spät dran, aber ich werde auch meine Lösung hinzufügen. Im Vergleich zu den Antworten hier ist das ein sehr viel schlauerer Ansatz.

Wenn Sie MongoDB Version 4.0 und Node.js 3.0 (oder höher) verwenden, können Sie auf jeden Fall isConnected() function aus der MongoClient verwenden.

const MongoClient = require('mongodb').MongoClient;
const uri = "<your connection url>";
const client = new MongoClient(uri, { useNewUrlParser: true });

if (client.isConnected()) {
  execute();
} else {
  client.connect().then(function () {
    execute();
  });
}

function execute() {
    // Do anything here
    // Ex: client.db("mydb").collection("mycol");
}

Das hat gut funktioniert für mich. Ich hoffe es hilft.

0