MongoDB: введение
Что такое MongoDB
MongoDB — документная NoSQL-СУБД.
Особенности:
- JSON-подобные документы (BSON).
- Гибкая схема — не обязательно, но рекомендуется.
- Горизонтальное масштабирование через шардирование.
- Репликация — Replica Set.
- Индексы — как в SQL, плюс специфичные.
- Aggregation Pipeline — мощный язык запросов.
- ACID транзакции с 4.0 (с ограничениями).
Лицензия: SSPL (не OSI-approved, но исходники открыты).
Термины
| SQL | MongoDB |
|---|---|
| database | database |
| table | collection |
| row | document |
| column | field |
| primary key | _id |
| index | index |
| JOIN | $lookup |
| GROUP BY | $group |
| transaction | transaction (4.0+) |
Ключевое: коллекция не требует схемы.
BSON
BSON — Binary JSON. Хранилище MongoDB.
Типы:
- string, int32, int64, double.
- Decimal128 — для денег.
- boolean, null.
- ObjectId — 12-байтовый ID.
- Date — timestamp.
- Array, Object.
- Binary, Regex.
- Timestamp — внутренний.
Decimal128 — единственный точный тип для денег.
Установка (Docker)
docker run -d \
--name mongo \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=secret \
-p 27017:27017 \
-v mongo_data:/data/db \
mongo:7
Docker Compose:
services:
mongo:
image: mongo:7
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: secret
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
volumes:
mongo_data:
Установка (Ubuntu)
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] \
https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt update
sudo apt install -y mongodb-org
sudo systemctl enable --now mongod
Подключение
MongoDB Shell (mongosh):
mongosh "mongodb://admin:secret@localhost:27017"
Внутри:
show dbs
use myapp
db.users.insertOne({ name: 'Алиса' })
db.users.find()
Основные команды
// Базы
show dbs
use myapp
db.dropDatabase()
// Коллекции
show collections
db.createCollection('users')
db.users.drop()
// Документы
db.users.insertOne({ ... })
db.users.insertMany([{ ... }, { ... }])
db.users.find()
db.users.findOne({ email: 'a@b.com' })
db.users.updateOne({ _id: 1 }, { $set: { name: 'X' } })
db.users.deleteOne({ _id: 1 })
db.users.countDocuments()
ObjectId
12 байт:
- 4 байта — timestamp.
- 5 байт — random.
- 3 байта — counter.
Что даёт:
- Уникален без координации.
- Сортируется по времени создания.
- Не угадывается.
В JSON:
{ "_id": { "$oid": "507f1f77bcf86cd799439011" } }
Генерация:
const id = new ObjectId()
Replica Set
Минимум для прода: 3 ноды.
Роли:
- Primary — принимает запись.
- Secondary — реплики.
- Arbiter — только голосует, без данных (не рекомендуется).
Что даёт:
- Автоматический failover.
- Read preference — можно читать с secondary.
- Durability через write concern.
Настройка (dev):
rs.initiate({
_id: 'rs0',
members: [
{ _id: 0, host: 'localhost:27017' },
{ _id: 1, host: 'localhost:27018' },
{ _id: 2, host: 'localhost:27019' },
],
})
Строка подключения:
mongodb://host1:27017,host2:27017,host3:27017/myapp?replicaSet=rs0
Write Concern
Сколько нод должны подтвердить запись:
db.users.insertOne({ ... }, { writeConcern: { w: 'majority' } })
Уровни:
w: 0— без подтверждения. Быстро, но не надёжно.w: 1— только primary. По умолчанию.w: 'majority'— большинство. Надёжно.w: 'majority', j: true— + запись в journal.
Правило: для критичных данных — majority + j: true.
Read Preference
Откуда читать:
primary— только primary. Свежие данные.primaryPreferred— primary, если недоступен — secondary.secondary— только secondary. Может отставать.secondaryPreferred— наоборот.nearest— ближайший по задержке.
В строке подключения:
mongodb://...?readPreference=secondaryPreferred
Строка подключения
mongodb://user:pass@host1:27017,host2:27017/myapp
?replicaSet=rs0
&readPreference=secondaryPreferred
&w=majority
&retryWrites=true
Параметры:
replicaSet— имя RS.readPreference— куда читать.w— write concern.retryWrites— авто-retry транзиентных ошибок.authSource— где искать пользователя.
Клиенты
Node.js:
npm install mongodb
# или
npm install mongoose
import { MongoClient } from 'mongodb';
const client = new MongoClient('mongodb://localhost:27017');
await client.connect();
const db = client.db('myapp');
const users = db.collection('users');
await users.insertOne({ name: 'Алиса' });
PHP:
composer require mongodb/mongodb
$client = new MongoDB\Client('mongodb://localhost:27017');
$users = $client->myapp->users;
$users->insertOne(['name' => 'Алиса']);
Python:
pip install pymongo
Mongoose (Node.js)
ODM для MongoDB:
import mongoose from 'mongoose';
const userSchema = new mongoose.Schema({
email: { type: String, required: true, unique: true },
name: { type: String, required: true },
age: { type: Number, min: 0 },
}, { timestamps: true });
const User = mongoose.model('User', userSchema);
await User.create({ email: 'a@b.com', name: 'Алиса' });
Что даёт:
- Схема в приложении.
- Валидация.
- Middleware (pre/post hooks).
- Populate (для связи).
Правило: даже в MongoDB — схема нужна. Mongoose её даёт.
Laravel + MongoDB
Пакет:
composer require mongodb/laravel-mongodb
class User extends \MongoDB\Laravel\Eloquent\Model
{
protected $connection = 'mongodb';
protected $collection = 'users';
}
User::create(['name' => 'Алиса']);
User::where('age', '>', 18)->get();
Что даёт: знакомый Eloquent.
⚠️ Eloquent-методы работают, но не всё — JOIN-ы эмулируются.
Админ-панели
- MongoDB Compass — официальная, GUI.
- mongosh — CLI.
- Studio 3T — платная, много фич.
- Robo 3T — бесплатная.
- NoSQLBooster — платная.
Compass — удобно для отладки запросов.
Коллекции и схемы
Схемы нет — но правила есть:
- Валидация через
$jsonSchema:
db.createCollection('users', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['email', 'name'],
properties: {
email: { bsonType: 'string', pattern: '^.+@.+$' },
name: { bsonType: 'string', maxLength: 100 },
age: { bsonType: 'int', minimum: 0 },
},
},
},
})
Что даёт: валидация на уровне БД.
Правило: в приложении — Mongoose/схема, в БД — $jsonSchema для доп. защиты.
Практика
1. Разверните MongoDB в Docker.
2. Подключитесь через mongosh.
3. Создайте базу myapp, коллекцию users.
4. Вставьте документ, найдите, обновите, удалите.
5. Создайте Replica Set из 3 нод (в Docker).
6. Подключитесь через строку с replicaSet.
7. Проверьте db.users.getIndexes().
Итог
- MongoDB — документная NoSQL.
- BSON — внутренний формат.
- ObjectId — 12 байт, сортируется по времени.
- Replica Set — 3+ ноды для прода.
- Write Concern:
majorityдля критичных. - Read Preference:
primaryдля свежих данных. - Mongoose — схема в приложении.
$jsonSchema— валидация в БД.
Дальше — документы и коллекции.