Что такое MongoDB и когда её использовать: честный разбор для разработчиков
MongoDB — это документная база данных, которая хранит данные в виде JSON-подобных документов вместо строк в таблицах. Если вы приходите из мира SQL, главное что нужно понять: в MongoDB нет таблиц с жёсткой схемой — есть коллекции документов с произвольной структурой. Это и главная сила, и главная ловушка MongoDB.
Как MongoDB устроена изнутри
Основные понятия
В MongoDB всё строится вокруг документа. Документ — это JSON-объект (технически BSON — бинарный JSON):
{
"_id": ObjectId("65f8a3b2c1d4e5f6a7b8c9d0"),
"name": "Иван Петров",
"email": "ivan@example.com",
"age": 32,
"address": {
"city": "Москва",
"street": "Ленина, 42"
},
"tags": ["developer", "python", "mongodb"],
"orders": [
{"product": "Книга", "price": 500, "date": "2026-01-15"},
{"product": "Курс", "price": 3000, "date": "2026-02-20"}
]
}
Сравним с реляционным подходом: в PostgreSQL для такой структуры понадобилось бы минимум 3 таблицы (users, addresses, orders) и JOIN при каждом запросе. В MongoDB — один документ.
Иерархия объектов MongoDB
- База данных (Database) — контейнер для коллекций, аналог schema в PostgreSQL
- Коллекция (Collection) — аналог таблицы, но без жёсткой схемы
- Документ (Document) — аналог строки, JSON-объект до 16 МБ
- Поле (Field) — аналог колонки, но у каждого документа могут быть разные поля
BSON vs JSON
MongoDB хранит данные в формате BSON (Binary JSON), который добавляет типы, не существующие в JSON:
ObjectId— уникальный 12-байтовый идентификаторDate— дата и время (а не строка)Int32,Int64— разные целые числаDecimal128— точная десятичная арифметика (для финансов)BinData— бинарные данные
Базовые операции: MongoDB vs SQL
Сравнение синтаксиса для разработчиков, знакомых с SQL:
Создание / вставка
// MongoDB
db.users.insertOne({
name: "Мария",
email: "maria@example.com",
role: "admin"
})
db.users.insertMany([
{ name: "Иван", role: "user" },
{ name: "Пётр", role: "user" }
])
-- PostgreSQL
INSERT INTO users (name, email, role) VALUES ('Мария', 'maria@example.com', 'admin');
Чтение
// MongoDB — найти все документы
db.users.find({})
// Найти с фильтром
db.users.find({ role: "admin" })
// Вложенное поле
db.users.find({ "address.city": "Москва" })
// Элемент массива
db.users.find({ tags: "developer" })
// Сложный запрос
db.users.find({
age: { $gte: 18, $lte: 35 },
role: { $in: ["admin", "moderator"] }
})
-- PostgreSQL эквиваленты
SELECT * FROM users WHERE role = 'admin';
SELECT * FROM users WHERE age BETWEEN 18 AND 35 AND role IN ('admin', 'moderator');
Обновление
// MongoDB
db.users.updateOne(
{ email: "ivan@example.com" },
{ $set: { role: "admin" }, $inc: { loginCount: 1 } }
)
// Добавить элемент в массив
db.users.updateOne(
{ email: "ivan@example.com" },
{ $push: { tags: "mongodb" } }
)
Удаление
db.users.deleteOne({ email: "ivan@example.com" })
db.users.deleteMany({ role: "inactive" })
Агрегация (аналог GROUP BY и JOIN)
// MongoDB Aggregation Pipeline
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $group: {
_id: "$userId",
totalSpent: { $sum: "$amount" },
orderCount: { $count: {} }
}},
{ $sort: { totalSpent: -1 } },
{ $limit: 10 }
])
MongoDB на Python: быстрый старт
pip install pymongo
from pymongo import MongoClient
from datetime import datetime
# Подключение
client = MongoClient('mongodb://localhost:27017/')
db = client['myapp']
users = db['users']
# Вставка
user_id = users.insert_one({
'name': 'Иван',
'email': 'ivan@example.com',
'created_at': datetime.now(),
'tags': ['python', 'mongodb']
}).inserted_id
print(f'Создан пользователь с id: {user_id}')
# Поиск
for user in users.find({'tags': 'python'}):
print(user['name'])
# Обновление
users.update_one(
{'email': 'ivan@example.com'},
{'$set': {'role': 'admin'}}
)
# Удаление
users.delete_one({'email': 'ivan@example.com'})
# Агрегация
pipeline = [
{'$group': {'_id': '$role', 'count': {'$sum': 1}}},
{'$sort': {'count': -1}}
]
for result in users.aggregate(pipeline):
print(result)
MongoDB с Mongoose (Node.js)
npm install mongoose
const mongoose = require('mongoose')
// Подключение
await mongoose.connect('mongodb://localhost:27017/myapp')
// Схема (опциональная, но рекомендуемая)
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
role: { type: String, enum: ['user', 'admin'], default: 'user' },
tags: [String],
createdAt: { type: Date, default: Date.now }
})
const User = mongoose.model('User', userSchema)
// CRUD операции
const user = await User.create({ name: 'Иван', email: 'ivan@example.com' })
const admins = await User.find({ role: 'admin' }).sort('-createdAt').limit(10)
await User.updateOne({ email: 'ivan@example.com' }, { role: 'admin' })
await User.deleteOne({ email: 'ivan@example.com' })
Когда MongoDB — правильный выбор
1. Данные с меняющейся структурой
Каталог товаров, где у каждого товара разный набор атрибутов:
// Электроника
{ "name": "Ноутбук", "ram": 16, "processor": "M3", "battery_hours": 18 }
// Одежда
{ "name": "Куртка", "sizes": ["S", "M", "L"], "material": "Полиэстер" }
// Еда
{ "name": "Кофе", "weight_g": 250, "roast": "dark", "origin": "Эфиопия" }
В PostgreSQL для этого нужна либо таблица с сотней NULL-колонок, либо EAV (Entity-Attribute-Value) — антипаттерн. MongoDB хранит это естественно.
2. Иерархические и вложенные данные
Системы управления контентом (CMS), профили пользователей, конфигурации приложений — всё что «живёт» в виде дерева.
3. Высокая скорость записи
MongoDB нативно поддерживает горизонтальное масштабирование через шардирование. Если нужно писать миллионы событий в секунду (IoT, логи, аналитика) — MongoDB масштабируется горизонтально проще, чем PostgreSQL.
4. Прототипирование и MVP
Когда схема данных ещё не определена, MongoDB позволяет итерировать быстро — добавлять и удалять поля без миграций. Для стартапа на ранней стадии это ценно.
5. Реальное время и стриминг
MongoDB Change Streams позволяют подписаться на изменения в коллекции в режиме реального времени — удобно для live-уведомлений, синхронизации данных.
6. AI и векторный поиск
С 2024 года MongoDB поддерживает Vector Search для хранения и поиска по эмбеддингам (Atlas Vector Search). Это позволяет строить RAG-системы без отдельного векторного хранилища.
Когда MongoDB — неправильный выбор
Когда данные сильно взаимосвязаны
Если у вас много JOIN-запросов между сущностями — MongoDB это не её сильная сторона. $lookup (аналог JOIN в MongoDB) значительно медленнее SQL JOIN и требует денормализации данных.
// MongoDB: неудобный "join"
db.orders.aggregate([
{
$lookup: {
from: 'users',
localField: 'userId',
foreignField: '_id',
as: 'user'
}
}
])
Когда нужны сложные транзакции
MongoDB поддерживает многодокументные транзакции с версии 4.0, но это исключение, а не норма. PostgreSQL с его ACID-гарантиями на уровне реляционных операций гораздо надёжнее для финансовых систем, бронирования, инвентаря.
Когда данные хорошо структурированы
Если у вас все пользователи имеют одинаковый набор полей, все заказы одинаковую структуру — MongoDB не даёт никаких преимуществ над PostgreSQL. Реляционная модель здесь проще и эффективнее.
Когда важна строгость данных
MongoDB по умолчанию не валидирует данные (можно включить schema validation, но это не дефолт). Это означает: можно вставить документ без обязательных полей, с неправильным типом данных. Для критически важных бизнес-данных это риск.
MongoDB vs PostgreSQL: итоговое сравнение
| Критерий | MongoDB | PostgreSQL | |---|---|---| | Модель данных | Документы (JSON/BSON) | Таблицы (строки, колонки) | | Схема | Гибкая, меняется без миграций | Жёсткая, требует миграций | | Транзакции | Поддерживает (с 4.0), но не главная сила | ACID, главная сила | | Горизонтальное масштабирование | Нативное шардирование | Через расширения (Citus) | | JOIN-запросы | Слабая сторона | Сильная сторона | | Агрегация | Мощный pipeline | Мощный SQL с оконными функциями | | Поддержка JSON | Нативно | JSONB с индексами | | Векторный поиск | Atlas Vector Search | pgvector | | Геопространственные данные | Встроенный GeoJSON | PostGIS | | Кривая обучения | Ниже для JS-разработчиков | Стандарт индустрии (SQL) | | Российские хостинги | Есть | Везде |
MongoDB в 2026: актуальное состояние
В 2026 году позиция MongoDB в экосистеме стабильна, но конкуренция усилилась:
- PostgreSQL с JSONB и pgvector закрывает многие use cases, которые раньше были зоной MongoDB
- MongoDB Atlas (облако) развивает нативную интеграцию с AI: Vector Search, Atlas Search, Data Federation
- FerretDB — open-source совместимый с MongoDB API движок на базе PostgreSQL (для тех, кто хочет MongoDB-синтаксис без лицензионных ограничений)
- Mongoose остаётся стандартом для Node.js, Beanie набирает популярность для Python
Если вы начинаете новый проект: PostgreSQL по умолчанию, MongoDB — когда есть конкретная причина.
Где запустить MongoDB
Локально
# Docker
docker run -d -p 27017:27017 --name mongo mongo:7
# Docker Compose
services:
mongo:
image: mongo:7
ports:
- "27017:27017"
volumes:
- ./mongodata:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
Облачные сервисы
- MongoDB Atlas (mongodb.com/atlas) — официальный облачный сервис, есть бесплатный M0 tier (512 МБ)
- Timeweb Cloud — MongoDB как управляемый сервис в России
- Selectel — MongoDB в российском облаке
- Railway — удобно для пет-проектов, есть MongoDB в каталоге (не российский)
Бэкапы MongoDB
# Создать дамп
mongodump --uri="mongodb://localhost:27017/mydb" --out=./backups/$(date +%Y%m%d_%H%M%S)
# Восстановить
mongorestore --uri="mongodb://localhost:27017/mydb" ./backups/20260501_143000/mydb/
# Для MongoDB Atlas — встроенный бэкап
# Dashboard → Database → Backup
Для автоматических бэкапов MongoDB в облако (Яндекс.Диск, S3, Google Drive) одной командой — смотрите dbsend.ru. Поддерживается mongodump с отправкой дампа в любое хранилище по расписанию.
FAQ
MongoDB — это NoSQL? Да. MongoDB относится к классу NoSQL (документные базы данных). NoSQL — не значит «без SQL». Это значит «не только SQL» — различные модели данных: документные (MongoDB), ключ-значение (Redis), графовые (Neo4j), колоночные (Cassandra).
Нужно ли знать схему заранее? Нет, это опционально. MongoDB позволяет вставлять документы без заранее определённой схемы. Но для продакшена рекомендуется использовать Mongoose (Node.js) или Beanie (Python) для валидации данных.
MongoDB бесплатная? Community Edition — полностью бесплатная. MongoDB Atlas имеет бесплатный tier (M0, 512 МБ). MongoDB Enterprise (для крупного бизнеса) — платная. Важно: в 2018 году MongoDB изменила лицензию на SSPL, что ограничивает использование в SaaS без раскрытия кода. Для замены — FerretDB (MIT лицензия).
Можно ли использовать SQL с MongoDB? Нет классического SQL. MongoDB использует MQL (MongoDB Query Language). Некоторые инструменты (MongoDB Connector for BI) позволяют делать SQL-запросы к MongoDB, но это надстройка.
Как MongoDB работает с транзакциями? С версии 4.0 MongoDB поддерживает многодокументные ACID-транзакции. Но архитектура MongoDB оптимизирована под атомарные операции на уровне одного документа. Транзакции — это вторичная возможность.
В чём разница между MongoDB и Redis? Redis — in-memory хранилище (данные в RAM), оптимизировано для скорости, используется как кэш, брокер сообщений или сессионное хранилище. MongoDB — дисковая база данных для персистентного хранения. Часто используются вместе: MongoDB для данных, Redis для кэша.
Как делать бэкапы MongoDB?
Через mongodump/mongorestore. Для Atlas — встроенный backup с Point-in-Time Recovery. Для автоматизации на своём сервере — dbsend.ru.