Node.js и MongoDB

Начало работы с MongoDB

Последнее обновление: 24.11.2023

Наиболее популярной системой управления базами данных для Node.js на данный момент является MongoDB. Для работы с этой платформой прежде всего необходимо установить сам сервер MongoDB. Подробнее как это сделать, описывается здесь. Кроме самого сервера Mongo для взаимодействия с Node.js нам необходим драйвер.

При подключении и взаимодействии с бд в MongoDB можно выделить следующие этапы:

  1. Подключение к серверу

  2. Получение объекта базы данных на сервере

  3. Получение объекта коллекции в базе данных

  4. Взаимодействие с коллекцией (добавление, удаление, получение, изменение данных)

Итак, создадим новый проект. Для этого определим новый каталог, который будет называться mongoapp. Далее перейдем к этому каталогу в командной строке/терминале и установим пакет mongodb:

npm install mongodb

Стоит отметить, что на момент написания текущей статьи текущая версия драйвера - 6.3.0. Между версиями и даже подверсиями иной раз бывают некоторые отличия. И в этом плане функционал драйвера очень часто меняется. Однако общие моменты часто сохраняются. Всю необходимую справочную информацию конкретно по данному драйверу можно найти на https://docs.mongodb.com/drivers/node/current/

Подключение к базе данных

Перед подключением к MongoDB из приложения на Node.js нам естественно сначала надо запустить сам сервер mongodb.

Ключевым классом для работы с MongoDB является класс MongoClient, и через него будет идти все взаимодействия с хранилищем данных. Соответственно вначале мы должны получить MongoClient:

const MongoClient = require("mongodb").MongoClient;

В конструктор MongoClient передается строка подключения к серверу:

"mongodb://user:password@host:port/?options

Элементы строки подключения

  • Сначала идет протокол, в качестве которого обычно применяется "mongodb".

  • Затем, если доступ к серверу ограничен логином и паролем, то указывается имя пользователя и через двоеточие пароль ("user:password").

  • Далее указывает хост и порт, по которому запущен сервер MongoDB (host:port).

  • В конце после вопросительного знака ? могут указываться дополнительные параметры подключения (?options.

Например, определим подключение к локальному серверу MongoDB, который запущен на текущем компьютере на стандартном адресе "127.0.0.1:27017/":

const MongoClient = require("mongodb").MongoClient;

const url = "mongodb://127.0.0.1:27017/";
// создаем объект MongoClient и передаем ему строку подключения
const mongoClient = new MongoClient(url);

Для подключения к серверу mongodb применяется метод connect():

connect(): Promise<MongoClient>

Метод возвращает Promise, из которого можно получить тот же объект MongoClient:

const MongoClient = require("mongodb").MongoClient;

const client = new MongoClient("mongodb://127.0.0.1:27017/");

client.connect().then(mongoClient=>{
    console.log("Подключение установлено");
    console.log(mongoClient.options.dbName); // получаем имя базы данных
});

Метод then() получает функцию, в которую передается подключенный MongoClient, по сути это тот же объект, что вызвал метод connect. Для теста с помощью свойства mongoClient.options.dbName выводим название базы данных, к которой мы подключены (по умолчанию это база данных test).

В конце завершения работы с бд нам надо закрыть соединение с помощью метода close().

const MongoClient = require("mongodb").MongoClient;

const client = new MongoClient("mongodb://127.0.0.1:27017/");

client.connect().then(mongoClient=>{
    console.log("Подключение установлено");
    // какие-нибудь операции с базой данных MongoDB
    // закрываем подключение
    mongoClient.close().then(()=>console.log("Подключение закрыто"));
});

Метод close() также возвращает Promise. Соответственно мы можем вызвать метод then() и в него передать функцию, которая выполняется при закрытии подключения.

Но лепить всю логику взаимодействия через вызовы then() может быть не очень удобно. Поэтому мы также можем использовать другой подход - с использованием async/await:

const MongoClient = require("mongodb").MongoClient;

const mongoClient = new MongoClient("mongodb://127.0.0.1:27017/");
async function run() {
	try {
		// Подключаемся к серверу
		await mongoClient.connect();
        console.log("Подключение установлено");
		// взаимодействие с базой данных
	}catch(err) {
		console.log(err);
	} finally {
		// Закрываем подключение при завершении работы или при ошибке
		await mongoClient.close();
        console.log("Подключение закрыто");
	}
}
run().catch(console.log);

База данных

После подлючения к серверу мы можем обращаться к базе данных на сервере. Для этого используется метод

const db = client.db("название_бд");

В качестве параметра в метод передается название базы данных, к которой мы хотим подключиться. Результатом функции является объект базы данных, через который мы далее уже сможем обращаться к данным в этой БД.

Для примера выполним ping к базе данных "admin", которая по умолчанию есть на сервере MongoDB:

const MongoClient = require("mongodb").MongoClient;
   
const url = "mongodb://127.0.0.1:27017/";
const mongoClient = new MongoClient(url);
async function run() {
	try {
		// Подключаемся к серверу
		await mongoClient.connect();
		// обращаемся к базе данных admin
		const db = mongoClient.db("admin");
		// выполняем пинг для проверки подключения
		const result = await db.command({ ping: 1 });
		console.log("Подключение с сервером успешно установлено");
		console.log(result);
	}catch(err) {
		console.log("Возникла ошибка");
		console.log(err);
	} finally {
		// Закрываем подключение при завершении работы или при ошибке
		await mongoClient.close();
		console.log("Подключение закрыто");
	}
}
run().catch(console.error);

Для выполнения диагностических команд типа пинга объект базы данных Db предоставляет метод command, который в качестве первого параметра принимает объект диагностики. Например, объект {ping: 1}, указывает, что надо выполнить пинг к базе данных, то есть проверить подключение к ней.

Метод command представляет Promise, из которого можно получить предоставляет результат проверки. В данном случае результат проверки возвращается в константу result .

const result = await db.command({ ping: 1 });

Запустим сервер MongoDb (если он не запущен) и затем запустим наш файл app.js:

Microsoft Windows [Version 10.0.22621.819]
(c) Корпорация Майкрософт (Microsoft Corporation). Все права защищены.

C:\Users\eugen>cd c:\node\mongoapp

c:\node\mongoapp>node app.js
Подключение с сервером успешно установлено
{ ok: 1 }
Подключение закрыто

c:\node\mongoapp>

Здесь мы видим, что полученный при пинге результат представляет объект {ok: 1}

Коллекции

База данных в MongoDB не имеет таблиц. Вместо этого все данные попадают в коллекции. И в рамках node.js для взаимодействия с базой данных (добавления, удаления, чтения данных) нам потребуется получить объект коллекции. Для этого применяется метод db.collection("название_коллекции"), в который передается название коллекции и который возвращает объект класса Collection, через который мы можем взаимодействовать с этой коллекцией.

В отличие от таблиц в реляционных системах, где все данные хранятся в виде строк, в коллекциях в MongoDB данные хранятся в виде документов. Например, обратимся к коллекции в базе данных. Для этого определим в каталоге проекта следующий файл app.js:

const MongoClient = require("mongodb").MongoClient;
   
const url = "mongodb://127.0.0.1:27017/";
const mongoClient = new MongoClient(url);

async function run() {
	try {
		await mongoClient.connect();
		const db = mongoClient.db("usersdb");
		const collection = db.collection("users");
		const count = await collection.countDocuments();
		console.log(`В коллекции users ${count} документов`);
	}catch(err) {
		console.log(err);
	} finally {
		await mongoClient.close();
	}
}
run().catch(console.error);

В качестве базы данных здесь используется "usersdb". При этом не важно, что по умолчанию на сервере MongoDB нет подобной базы данных. При первом к ней обращении сервер автоматически ее создаст.

После подключения мы обращаемся к коллекции "users":

const collection = db.collection("users");

Опять же неважно, что такой коллекции по умолчанию нет в бд usersdb, она также будет создана при первом обращении.

Получив коллекцию, мы можем использовать ее методы. В данном случае для простоты применяется метод countDocuments(), который получает количество документов коллекции. Этот метод возвращает Primise, из которого можно получить собственно результат операции - количество документов. Результат работы:

В коллекции users 0 документов
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850