Подтвердить что ты не робот

Как я могу структурировать свое экспресс-приложение, где мне нужно только открыть соединение mongodb?

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

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

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

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

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

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

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

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

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

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

Благодаря.

EDIT

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

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

И в файле маршрутов JS это начинается так:

module.exports = function(app){

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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;

Ответ 3

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

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

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

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

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);
    });
};