2012-03-10 1 views
16

Примечание: прочитайте отредактированную часть этого сообщения перед ответом, это может сэкономить ваше время и ответить на один из моих вопросов.Как я могу структурировать мое экспресс-приложение, где мне нужно только открыть соединение mongodb?

Проблема, с которой я столкнулся, довольно проста, но я довольно новичок в этом отношении, и у меня возникают проблемы с выяснением того, как правильно использовать соединение с базой данных mongodb в приложении node/express.

Я использую экспресс 3.x, и я основывая свое приложение расположение вокруг этого проекта, предоставленного автором экспресса: https://github.com/visionmedia/express/tree/master/examples/blog

Я не заинтересован в том, блог, тем не менее, как приложение структурировано появится быть довольно приятным. Маршруты разделены, и все организовано красиво.

Моя проблема заключается в том, что у меня может быть 5-6 разных файлов js маршрута, и каждый файл js маршрута может иметь от 1 до 15 маршрутов; из этих маршрутов 1 или 15 может потребоваться доступ к db.

Итак, моя проблема - это действительно ужасная идея сделать db.open (...) каждый раз, когда я хочу запросить db. Я должен упомянуть, что на данный момент я использую собственный драйвер mongo-db (npm install mongodb).

Я также должен был бы включать в файл, как это: http://pastebin.com/VzFsPyax

... во всех этих файлов маршрутов и все мои файлы модели. Тогда я также имею дело с десятками на десятки открытых связей.

Есть ли способ структурировать мое приложение таким образом, что я делаю только одно соединение, и он остается открытым в течение всего сеанса (с новым, сделавшим каждый запрос тоже плохо)?

Если да, то как я могу это сделать? Если вы знаете ответ, отправьте образец кода, используя в качестве базового руководства приложение blog (приложение, связанное ранее в этой статье). В основном есть способ, которым маршруты и модели могут свободно использовать db, находясь в отдельных файлах, чем открытый код db.

Спасибо.

EDIT

Я сделал некоторый прогресс в решении одной из моих вопросов. Если посмотреть на пример блога Tj, он инициализирует свои маршруты в app.js так:

require('./routes/site')(app); 
require('./routes/post')(app); 

И в маршрутах подать JS он начинает так:

module.exports = function(app){ 

я наткнулся на проект ранее сегодня, когда я увидел, что кто-то передал 2 переменные в функции modules.exports call -> (app, db). Тогда, очевидно, ничего себе не может быть так просто, мне нужно просто настроить мои маршруты (приложение, db) тоже? Да, похоже.

Итак, теперь часть 1 проблемы решена. Мне не нужно требовать файл mongo.js с шаблоном подключения в каждом файле маршрута. В то же время он достаточно гибкий, и я могу решить выбрать, какие файлы маршрутов передают ссылку на db. Это стандарт и не имеет недостатка?

Часть 2 проблемы (важный, к сожалению) все еще существует.

Как я могу обойти необходимость делать db.open (...) вокруг каждого запроса, который я делаю, и в идеале делать соединение только один раз за сеанс?

+0

https: // gist.github.com/1946211 – Raynos

+0

Как это помогает моей ситуации, можете ли вы немного разобраться в том, что происходит с вашим код? – AntelopeSalad

+0

Открывает одно соединение для каждой коллекции. – Raynos

ответ

1

Действительно глупо. В документации кажется, что db.open требует обернуть вокруг того, что его использует, но на самом деле вы можете использовать его без обратного вызова.

Итак, ответ заключается в том, чтобы просто сделать db.open() в вашем подключаемом модуле подключения к базе данных, файле app.js или когда вы решите настроить свой сервер/соединение на сервере.

До тех пор, пока вы передаете ссылку на db в файлах, используя это, вы получите доступ к «открытому» соединению db, готовому для запроса.

+0

Примечание: Я не буду отмечать себя как правильное, но, возможно, существуют препятствия, связанные с этим (проблемы с производительностью?). Может быть, эксперт MongoDB может перезвонить! – AntelopeSalad

+1

Как вы получаете объект db, если не как параметр функции обратного вызова? – Shawn

+1

MongoClient.open() возвращает null (http://mongodb.github.io/node-mongodb-native/api-generated/mongoclient.html#open), так что MongoClient.connect() (http: //mongodb.github .io/узел-MongoDB-родной/API-порожденных/mongoclient.html # mongoclient-соединение). Эти ответы не кажутся правильными. – thertweck

3

Я сделал очень простой модуль hub для этого случая, который заменяет использование глобального пространства.

В app.js вы можете создать соединение с базой данных сразу:

var hub = require('hub'); 
hub.db = new Db('foobar', new Server('10.0.2.15', 27017, {}), {native_parser: false}); 

и использовать его с любыми другими файлами:

var hub = require('hub'); 
// hub.db - here link to db connection 

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

UPDATE

Вот что я имею в виду:

В главном файле, как app.js мы создаем Db соединение, откройте его и хранить в ступицу:

app.js:

var hub = require('hub'); 
hub.mongodb = require('mongodb'); 
hub.mongodbClient = new hub.mongodb.Db('foobar', new hub.mongodb.Server('10.0.2.15', 27017, {}), {native_parser: false}); 
hub.mongodbClient.open(function(error) { 
    console.log('opened'); 
}); 

Теперь в любом другом файле (например, сообщение) мы имеем доступ к открытому соединению и можем его просто использовать:

message.js:

var hub = require('hub'); 
var collection = new hub.mongodb.Collection(hub.mongodbClient, 'message'); 

module.exports.count = function(cb) { 
    collection.count({}, function(err, count) { 
     cb(err, count); 
    }); 
}; 
+0

Это то, что я сейчас делаю. У меня есть файл mongo.js с 3 строками (setup db), а затем я требую его в маршрутах/моделях, где я его использую. Проблема заключается в том, что каждый раз, когда я хочу использовать db, я должен обернуть db.open (...) вокруг запроса, который я хочу использовать. – AntelopeSalad

+0

@ Рейоны действительно? Это просто и работает. Ваши варианты? Каким образом вы можете использовать общие ресурсы (например, соединения БД, конфигурации, строки локалей) из разных модулей? –

+0

@Vadim Проверьте, что я добавил в свой вопрос под «edit». Разве это не устраняет необходимость в концентраторе или любом избыточном типе? – AntelopeSalad

15

Другое решение передать базу данных к маршрутизатору через запрос, например:

app.js

var db = openDatabase(); 

var app = express(); 

app.all('*', function(request, response, next) 
    { 
    request.database = db; 
    next(); 
    }); 

app.get('/api/user/:id', Users.getByID); 

users.js

var Users = 
    { 
    getByID: function(request, response) 
     { 
     request.database.collection('users').findOne(...) 
     response.send(user); 
     } 
    }; 

module.exports = Users; 
+0

Возможно, я что-то пропустил, но не должен app.js -> app.all -> request.database = db; ? (vs. request.database = database) ...? – August

+1

Да исправлено, спасибо –

+0

Как сделать функцию openDatabase синхронной? Я знаю, что есть еще один модуль, такой как монгоскин и монах, но они поставляются с некоторыми другими проблемами. –

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