2013-08-04 3 views
12

Я использую mongodb-native-driver в приложении express.js. У меня около 6 коллекций в базе данных, поэтому я создал 6 js-файлов, каждый из которых имеет коллекцию как объект javascript (например, function collection(){}), а функции прототипов обрабатывают все манипуляции с этими коллекциями. Я думал, что это будет хорошая архитектура.Подключение к Mongodb-родной-Driver в express.js

Но проблема у меня есть Как подключиться к базе данных? Должен ли я создать соединение в каждом из этих файлов и использовать их? Я думаю, что это было бы излишним, поскольку соединение в mongodb-native-driver создает пул соединений, и некоторые из них не будут оправданы.

Как я могу создать единственный пул соединений и использовать его во всех файлах collections.js? Я хочу, чтобы соединение было реализовано в мангусте. Дайте мне знать, если какой-либо из моих мыслительных процессов в архитектуре приложения ошибочен.

Использование Mongoose решит эти проблемы, но я прочитал в нескольких местах, что это медленнее, чем родной драйвер, а также я бы предпочел модели без схемы.

Редактировать: Я создал модуль из моделей. Каждая коллекция находилась в файле, и в качестве аргумента использовалась база данных. Теперь в файле index.js я вызвал соединение с базой данных и сохранил переменную db после того, как я получил базу данных из соединения. (Я использовал функцию автоматического повторного подключения, чтобы убедиться, что соединение не было потеряно). В том же index.js файла я экспортировал каждый из коллекций, как этого

exports.model1 = require('./model1').(db) 
exprorts.model2 = require('./model2').(db) 

Это гарантировало, что часть базы данных обрабатывается только один модуль и приложение будет просто вызвать функцию, что каждый файл model.js экспортированную как save() , fincdbyid() и т. Д. (whatever you do in the function is upto you to implement).

ответ

17

Как подключиться к базе данных?

Для того, чтобы подключиться с помощью встроенного драйвера MongoDB, что вам нужно сделать что-то вроде следующего:

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

var auth = { 
    user: 'username', 
    pass: 'password', 
    host: 'hostname', 
    port: 1337, 
    name: 'databaseName' 
}; 

var uri = util.format('mongodb://%s:%[email protected]%s:%d/%s', 
    auth.user, auth.pass, auth.host, auth.port, auth.name); 

/** Connect to the Mongo database at the URI using the client */ 
client.connect(uri, { auto_reconnect: true }, function (err, database) { 
    if (err) throw err; 
    else if (!database) console.log('Unknown error connecting to database'); 
    else { 

     console.log('Connected to MongoDB database server at:'); 
     console.log('\n\t%s\n', uri); 

     // Create or access collections, etc here using the database object 
    } 
}); 

Основное соединение установки, как это. Это все, что я могу дать вам, просто базовое описание того, что вы хотите. Опубликуйте код, который у вас есть, чтобы получить более конкретную помощь.

Должен ли я создать соединение в каждом из этих файлов и использовать их?

No.

Так как же создать единый пул соединений и использовать его во всех collections.js файлов?

Вы можете создать один файл с таким кодом, как указано выше, позвоните ему dbmanager.js, подключившись к базе данных. Экспортные функции, такие как createUser, deleteUser и т. Д.которые работают на базе данных, а затем экспортировать функциональность как так:

module.exports = { 
    createUser: function() { ; }, 
    deleteUser: function() { ; } 
}; 

который затем require из другого файла, как так могло:

var dbman = require('./dbmanager'); 

dbman.createUser(userData); // using connection established in `dbmanager.js` 

EDIT: Поскольку мы имеем дело с JavaScript и а одиночный поток, родной драйвер действительно автоматически обрабатывает пул соединений для вас. Вы можете найти это в ссылках StackOverflow ниже, чтобы получить больше подтверждения. ОП указывает это и в вопросе. Это означает, что client.connect следует называть только один раз экземпляром вашего сервера. После того как объект database успешно извлекается из вызова client.connect, объект database должен быть повторно использован во всем экземпляре вашего приложения. Это легко осуществить, используя шаблон модуля, который предоставляет Node.JS.

Мое предложение состоит в том, чтобы создать модуль или набор модулей, которые служат единой точкой контакта для взаимодействия с базой данных. В моих приложениях у меня обычно есть один модуль, который зависит от собственного драйвера, вызывающего require('mongodb'). Все остальные модули в моем приложении не будут напрямую обращаться к базе данных, но вместо этого все манипуляции должны координироваться этим модулем базы данных.

Это инкапсулирует весь код, связанный с собственным драйвером, в один модуль или набор модулей. Кажется, что OP думает, что есть проблема с простым примером кода, который я опубликовал, описывая проблему с «одним большим закрытием» в моем примере. Все это довольно простой материал, поэтому я добавляю разъяснения относительно базовой архитектуры здесь, но я все еще не чувствую необходимости изменять какой-либо код.

OP также, кажется, думает, что здесь возможно сделать несколько соединений. Это невозможно с этой настройкой. Если вы создали такой модуль, как я предлагаю выше, то в первый раз, когда require('./dbmanager') называется, он выполнит код в файле dbmanager.jsи возвращает объект module.exports. Объект экспорта кэшируется и также возвращается при каждом последующем вызове require('./dbmanager'), однако код в dbmanager.js будет выполнен только первым require.

Если вы не хотите создавать такой модуль, то другой вариант должен был экспортировать только database, переданный на обратный вызов для client.connect, и использовать его непосредственно в разных местах вашего приложения. Тем не менее, я рекомендую против этого, независимо от проблем с OP.

Похоже, возможно, дублировать StackOverflow вопросы, среди прочего:

+0

Я рассмотрел решение, которое вы дали, но не пошел дальше, потому что, как я уже сказал выше, у меня есть около 6 коллекций и идея написать все манипуляции внутри одного большого закрытия. Во-вторых, в вашем методе есть вероятность, что может быть сделано несколько соединений, поскольку он не проверяет наличие уже подключенного или нет. –

+0

Независимо от того, сколько раз вы требуете (./dbmanager), он не будет называть 'client.connect' несколько раз. Единственный «шанс», что будет сделано более одного соединения, - это запустить несколько экземпляров сервера. Node.JS будет выполнять код только в первый раз, когда требуется, возвращая только «экспорт» с каждым последующим вызовом. –

+0

-1 отсутствует в объяснении. Вопреки вашему комментарию, вы никогда не упоминаете ничего об одном закрытии в своем вопросе. Я специально отвечаю на каждый из ваших вопросов: они касались того, следует ли создавать соединения в нескольких разных файлах. Я поддерживаю свой ответ: это необязательно. –

2

Как говорит принят ответ - вы должны создать только одно соединение для всех входящих запросов и повторно использовать его, но ответ отсутствует, что приведет к созданию и кэш-соединению. Для этого я написал специальное промежуточное программное обеспечение - express-mongo-db.На первый взгляд эта задача тривиальна, и большинство людей используют этот вид кода:

var db; 
function createConnection(req, res, next) { 
    if (db) { req.db = db; next(); } 
    client.connect(uri, { auto_reconnect: true }, function (err, database) { 
     req.db = db = databse; 
     next(); 
    }); 
} 

app.use(createConnection); 

Но этот код приведет вас к разъему-утечки, когда несколько запрос приходит в то же самое время, и db не определен. express-mongo-db, разрешая это, удерживая входящих клиентов и вызывая connect только один раз, когда требуется модуль (не когда приходит первый запрос).

Упование вы считаете это полезным.

0

Я просто думал, что я хотел бы добавить в мой собственный метод связи MongoDB для других заинтересованных или имеющих проблемы с различными методами

Этот метод предполагает, что вам не нужно аутентификации (я использую это на локальном хосте)

Аутентификация по-прежнему легко реализовать

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

var client = new MongoClient(new Server('localhost',27017,{ 
           socketOptions: {connectTimeoutMS: 500}, 
           poolSize:5, 
           auto_reconnect:true 
          }, { 
           numberOfRetries:3, 
           retryMilliseconds: 500 
          })); 

client.open(function(err, client) { 
    if(err) { 
     console.log("Connection Failed Via Client Object."); 
    } else { 
     var db = client.db("theDbName"); 
     if(db) { 
      console.log("Connected Via Client Object . . ."); 
      db.logout(function(err,result) { 
       if(!err) { 
        console.log("Logged out successfully"); 
       } 
       client.close(); 
       console.log("Connection closed"); 
      }); 
     } 
    } 
}); 

Заслуга Брэд Davley, который идет по этому методу в его book (стр 231-232)

Смежные вопросы