Mongoose для JavaScript (Node.js): полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Что такое Mongoose и зачем он нужен?

Mongoose — это Object Data Modeling (ODM) библиотека для MongoDB и Node.js. Она предоставляет мощный, основанный на схемах способ моделирования данных вашего приложения. Если вы работаете с MongoDB в среде Node.js, Mongoose является де-факто стандартом для управления данными.

Зачем он нужен? MongoDB — это NoSQL база данных, которая хранит данные в виде JSON-подобных документов. В отличие от реляционных баз данных, она не требует строгой схемы. Это дает гибкость, но может привести к хаосу в больших проектах. Mongoose решает эту проблему, добавляя слой абстракции, который:

  • Определяет схемы (Schemas): Вы описываете структуру ваших документов: какие поля есть, какого они типа, какие значения по умолчанию, обязательны ли они.
  • Валидирует данные: Перед сохранением в базу данных Mongoose проверяет, соответствуют ли данные вашей схеме. Это предотвращает запись "мусорных" данных.
  • Предоставляет удобные методы: Вместо написания сырых запросов к MongoDB, вы используете интуитивно понятные методы, такие как .find(), .create(), .updateOne().
  • Управляет связями: Вы можете легко связывать документы из разных коллекций (например, пользователя и его заказы) с помощью populate().
  • Middleware (хуки): Позволяет выполнять код до или после определенных операций (например, хешировать пароль перед сохранением).

Простыми словами: Mongoose — это "мостик" между вашим JavaScript-кодом и MongoDB, который делает работу с базой данных структурированной, безопасной и удобной.

Установка Mongoose

Установка Mongoose в ваш Node.js проект выполняется через npm (Node Package Manager). Убедитесь, что у вас установлен Node.js и npm.

Откройте терминал в корне вашего проекта и выполните команду:

npm install mongoose

Эта команда установит последнюю стабильную версию Mongoose и добавит ее в ваш файл package.json в секцию dependencies.

Также вам потребуется установленный и запущенный сервер MongoDB. Вы можете установить его локально или использовать облачный сервис, такой как MongoDB Atlas.

Быстрый старт с примером кода

Давайте создадим простое приложение, которое подключается к MongoDB и сохраняет информацию о пользователе.

  1. Подключаем Mongoose к базе данных:
// app.js
const mongoose = require('mongoose');

// Строка подключения к MongoDB (замените 'mydatabase' на имя вашей БД)
const mongoURI = 'mongodb://localhost:27017/mydatabase';

mongoose.connect(mongoURI)
  .then(() => console.log('Успешно подключено к MongoDB!'))
  .catch(err => console.error('Ошибка подключения:', err));
  1. Определяем схему и модель:
// Определяем схему (Schema) для пользователя
const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  age: { type: Number, default: 18 }
});

// Создаем модель (Model) на основе схемы
const User = mongoose.model('User', userSchema);
  1. Создаем и сохраняем документ:
async function createUser() {
  try {
    // Создаем экземпляр модели
    const newUser = new User({
      name: 'Иван Иванов',
      email: 'ivan@example.com',
      age: 30
    });

    // Сохраняем пользователя в базу данных
    const savedUser = await newUser.save();
    console.log('Пользователь сохранен:', savedUser);
  } catch (error) {
    console.error('Ошибка при сохранении:', error.message);
  }
}

createUser();

После запуска этого кода, в вашей базе данных MongoDB появится коллекция users с документом, содержащим данные пользователя.

Основные методы и функции Mongoose (8-10 штук)

1. mongoose.connect(uri, options)

Что делает: Устанавливает соединение с MongoDB. Это первый шаг для работы с библиотекой.

Параметры:

  • uri (String): Строка подключения к MongoDB (например, mongodb://localhost:27017/mydb).
  • options (Object, необязательный): Объект с настройками подключения (например, { useNewUrlParser: true, useUnifiedTopology: true }).

Пример:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/testdb', {
  useNewUrlParser: true,
  useUnifiedTopology: true
})
.then(() => console.log('Подключено'))
.catch(err => console.log('Ошибка:', err));

2. new mongoose.Schema(definition, options)

Что делает: Создает новую схему (Schema). Схема определяет структуру документов в коллекции.

Параметры:

  • definition (Object): Объект, описывающий поля и их типы (например, { name: String, age: Number }).
  • options (Object, необязательный): Настройки схемы (например, { timestamps: true } для автоматического добавления полей createdAt и updatedAt).

Пример:

const bookSchema = new mongoose.Schema({
  title: { type: String, required: true },
  author: String,
  pages: Number,
  published: { type: Date, default: Date.now }
}, { timestamps: true });

3. mongoose.model(name, schema)

Что делает: Создает модель (Model) на основе схемы. Модель — это класс, с помощью которого вы создаете и запрашиваете документы из коллекции.

Параметры:

  • name (String): Имя модели. Mongoose автоматически создаст коллекцию с именем во множественном числе (например, User -> коллекция users).
  • schema (Schema): Схема, на основе которой создается модель.

Пример:

const Book = mongoose.model('Book', bookSchema);
// Теперь Book — это модель для работы с коллекцией 'books'

4. Model.create(doc(s))

Что делает: Создает и сохраняет один или несколько документов в базе данных за одну операцию. Это более лаконичная альтернатива new Model() + .save().

Параметры:

  • doc(s) (Object | Array): Один объект или массив объектов для сохранения.

Пример:

// Создание одного документа
const newBook = await Book.create({ title: 'Война и мир', author: 'Толстой', pages: 1225 });

// Создание нескольких документов
const books = await Book.create([
  { title: '1984', author: 'Оруэлл', pages: 328 },
  { title: 'Мастер и Маргарита', author: 'Булгаков', pages: 480 }
]);

5. Model.find(filter, projection, options)

Что делает: Находит все документы, соответствующие условиям фильтра. Возвращает массив документов.

Параметры:

  • filter (Object): Условия поиска (например, { author: 'Толстой' }).
  • projection (Object | String, необязательный): Какие поля включить/исключить (например, { title: 1, _id: 0 }).
  • options (Object, необязательный): Дополнительные опции (например, { limit: 10, sort: { pages: -1 } }).

Пример:

// Найти все книги Толстого, показать только названия
const booksByTolstoy = await Book.find(
  { author: 'Толстой' },
  { title: 1, _id: 0 }
);
console.log(booksByTolstoy); // [{ title: 'Война и мир' }, ...]

6. Model.findById(id, projection, options)

Что делает: Находит один документ по его _id. Это самый быстрый способ найти документ по первичному ключу.

Параметры:

  • id (ObjectId | String): Идентификатор документа.
  • projection (Object | String, необязательный): Какие поля включить/исключить.
  • options (Object, необязательный): Дополнительные опции.

Пример:

const bookId = '60f7b1c5b3f1a72d8c9e1234'; // Пример ID
const book = await Book.findById(bookId);
console.log(book.title); // Выведет название книги

7. Model.findOne(filter, projection, options)

Что делает: Находит первый документ, соответствующий условиям фильтра. Отличается от find() тем, что возвращает один объект, а не массив.

Параметры:

  • filter (Object): Условия поиска.
  • projection (Object | String, необязательный): Какие поля включить/исключить.
  • options (Object, необязательный): Дополнительные опции.

Пример:

// Найти первую книгу с количеством страниц больше 500
const thickBook = await Book.findOne({ pages: { $gt: 500 } });
console.log(thickBook.title);

8. Model.findByIdAndUpdate(id, update, options)

Что делает: Находит документ по ID и обновляет его. Может вернуть старый или новый документ в зависимости от опции new.

Параметры:

  • id (ObjectId | String): Идентификатор документа.
  • update (Object): Объект с обновлениями (например, { $set: { pages: 1300 } }).
  • options (Object, необязательный): { new: true } — вернуть обновленный документ; { runValidators: true } — запустить валидацию.

Пример:

const updatedBook = await Book.findByIdAndUpdate(
  bookId,
  { $set: { pages: 1300 } },
  { new: true, runValidators: true }
);
console.log(updatedBook.pages); // 1300

9. Model.findByIdAndDelete(id)

Что делает: Находит документ по ID и удаляет его из базы данных. Возвращает удаленный документ.

Параметры:

  • id (ObjectId | String): Идентификатор документа для удаления.

Пример:

const deletedBook = await Book.findByIdAndDelete(bookId);
if                    

Рекомендаций