- Home »

Как создавать запросы в MongoDB
Работа с MongoDB – это не просто NoSQL-хайп, это реально мощная штука для тех, кто хочет быстро и эффективно работать с данными. Если ты уже имел дело с MySQL или PostgreSQL, то MongoDB откроет для тебя совершенно новые возможности. Сегодня разберём, как правильно создавать запросы в MongoDB, какие есть подводные камни и как не наступить на все грабли сразу. После этого поста ты сможешь уверенно крутить данные, создавать эффективные запросы и понимать, когда MongoDB – это именно то, что тебе нужно.
Как работает система запросов MongoDB
В отличие от привычного SQL, MongoDB использует документо-ориентированный подход. Данные хранятся в формате BSON (Binary JSON), что делает запросы более гибкими, но требует другого мышления.
Основные принципы:
- Коллекции вместо таблиц – группы документов
- Документы вместо строк – JSON-подобные объекты
- Поля вместо столбцов – могут быть вложенными
- Гибкая схема – документы в одной коллекции могут иметь разную структуру
Запросы в MongoDB строятся через методы JavaScript-подобного API. Вместо SELECT используется find(), вместо INSERT – insertOne() или insertMany().
Установка и базовая настройка
Начнём с установки MongoDB на сервер. Для продакшена рекомендую использовать VPS или выделенный сервер с достаточным объёмом RAM.
# Ubuntu/Debian
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
# Запуск и автозагрузка
sudo systemctl start mongod
sudo systemctl enable mongod
# Проверка статуса
sudo systemctl status mongod
Подключение к MongoDB:
# Локальное подключение
mongosh
# Подключение к удалённому серверу
mongosh "mongodb://username:password@your-server:27017/database"
Создание и использование базы данных
В MongoDB базы данных создаются автоматически при первом обращении:
# Выбор/создание базы данных
use myapp
# Просмотр текущей базы
db
# Список всех баз данных
show databases
# Создание коллекции
db.createCollection("users")
# Просмотр коллекций
show collections
Основные типы запросов
Создание документов (CREATE)
# Вставка одного документа
db.users.insertOne({
name: "John Doe",
email: "john@example.com",
age: 30,
skills: ["JavaScript", "Python", "MongoDB"]
})
# Вставка нескольких документов
db.users.insertMany([
{
name: "Jane Smith",
email: "jane@example.com",
age: 25,
department: "Development"
},
{
name: "Bob Johnson",
email: "bob@example.com",
age: 35,
department: "DevOps"
}
])
Чтение документов (READ)
# Получение всех документов
db.users.find()
# Поиск с условием
db.users.find({name: "John Doe"})
# Поиск с операторами сравнения
db.users.find({age: {$gte: 30}})
# Поиск по массиву
db.users.find({skills: "MongoDB"})
# Поиск с регулярными выражениями
db.users.find({name: /^John/i})
# Ограничение результатов
db.users.find().limit(5)
# Сортировка
db.users.find().sort({age: -1})
# Проекция (выбор полей)
db.users.find({}, {name: 1, email: 1, _id: 0})
Обновление документов (UPDATE)
# Обновление одного документа
db.users.updateOne(
{name: "John Doe"},
{$set: {age: 31}}
)
# Обновление нескольких документов
db.users.updateMany(
{department: "Development"},
{$set: {bonus: 1000}}
)
# Добавление элемента в массив
db.users.updateOne(
{name: "John Doe"},
{$push: {skills: "Docker"}}
)
# Удаление поля
db.users.updateOne(
{name: "John Doe"},
{$unset: {bonus: ""}}
)
Удаление документов (DELETE)
# Удаление одного документа
db.users.deleteOne({name: "John Doe"})
# Удаление нескольких документов
db.users.deleteMany({age: {$lt: 25}})
# Удаление всех документов из коллекции
db.users.deleteMany({})
Продвинутые запросы и операторы
Логические операторы
# AND (по умолчанию)
db.users.find({
age: {$gte: 25},
department: "Development"
})
# OR
db.users.find({
$or: [
{age: {$lt: 25}},
{department: "DevOps"}
]
})
# NOT
db.users.find({
age: {$not: {$gte: 30}}
})
# NOR
db.users.find({
$nor: [
{age: {$lt: 25}},
{department: "HR"}
]
})
Операторы для массивов
# Поиск документов с определённым элементом в массиве
db.users.find({skills: "MongoDB"})
# Поиск по размеру массива
db.users.find({skills: {$size: 3}})
# Поиск всех элементов массива
db.users.find({skills: {$all: ["JavaScript", "MongoDB"]}})
# Поиск по элементам массива с условием
db.users.find({skills: {$elemMatch: {$regex: /Java/}}})
Агрегационные запросы
Агрегация – это мощный инструмент для обработки данных:
# Группировка по полю
db.users.aggregate([
{$group: {
_id: "$department",
count: {$sum: 1},
avgAge: {$avg: "$age"}
}}
])
# Фильтрация и сортировка
db.users.aggregate([
{$match: {age: {$gte: 25}}},
{$sort: {age: -1}},
{$limit: 10}
])
# Добавление вычисляемых полей
db.users.aggregate([
{$addFields: {
isExperienced: {$gte: ["$age", 30]},
skillCount: {$size: "$skills"}
}}
])
# Развёртывание массивов
db.users.aggregate([
{$unwind: "$skills"},
{$group: {
_id: "$skills",
count: {$sum: 1}
}}
])
Индексы для оптимизации производительности
Без индексов MongoDB будет сканировать всю коллекцию:
# Создание простого индекса
db.users.createIndex({email: 1})
# Составной индекс
db.users.createIndex({department: 1, age: -1})
# Индекс для текстового поиска
db.users.createIndex({name: "text", email: "text"})
# Уникальный индекс
db.users.createIndex({email: 1}, {unique: true})
# Просмотр индексов
db.users.getIndexes()
# Удаление индекса
db.users.dropIndex({email: 1})
# Анализ производительности
db.users.find({email: "john@example.com"}).explain("executionStats")
Сравнение с другими решениями
Критерий | MongoDB | MySQL | PostgreSQL |
---|---|---|---|
Схема данных | Гибкая, документо-ориентированная | Жёсткая, табличная | Гибкая, с поддержкой JSON |
Горизонтальное масштабирование | Встроенный шардинг | Требует дополнительных решений | Сложное |
Транзакции | Есть (с версии 4.0) | ACID-совместимые | ACID-совместимые |
Изучение | Среднее | Простое | Сложное |
Производительность на чтение | Высокая | Средняя | Средняя |
Практические примеры и кейсы
Система логирования
# Создание коллекции логов
db.logs.insertMany([
{
timestamp: new Date(),
level: "error",
message: "Database connection failed",
service: "api-server",
metadata: {
userId: "12345",
endpoint: "/api/users"
}
},
{
timestamp: new Date(),
level: "info",
message: "User logged in",
service: "auth-service",
metadata: {
userId: "67890",
ip: "192.168.1.100"
}
}
])
# Поиск ошибок за последний час
db.logs.find({
level: "error",
timestamp: {$gte: new Date(Date.now() - 3600000)}
})
# Группировка по уровню логирования
db.logs.aggregate([
{$group: {
_id: "$level",
count: {$sum: 1}
}}
])
Каталог товаров
# Создание товаров с различной структурой
db.products.insertMany([
{
name: "Laptop",
price: 999.99,
category: "Electronics",
specs: {
cpu: "Intel i7",
ram: "16GB",
storage: "512GB SSD"
},
tags: ["computer", "portable", "work"]
},
{
name: "T-Shirt",
price: 19.99,
category: "Clothing",
specs: {
size: "M",
color: "Blue",
material: "Cotton"
},
tags: ["casual", "comfortable"]
}
])
# Поиск товаров по диапазону цен
db.products.find({
price: {$gte: 10, $lte: 50}
})
# Текстовый поиск
db.products.createIndex({name: "text", tags: "text"})
db.products.find({$text: {$search: "computer portable"}})
Автоматизация и скрипты
MongoDB отлично интегрируется с различными языками программирования:
# Python с pymongo
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client['myapp']
collection = db['users']
# Пакетная вставка
users = [
{"name": "User1", "email": "user1@example.com"},
{"name": "User2", "email": "user2@example.com"}
]
collection.insert_many(users)
# Поиск с обработкой
for user in collection.find({"age": {"$gte": 18}}):
print(f"Adult user: {user['name']}")
# Node.js с официальным драйвером
const { MongoClient } = require('mongodb');
async function main() {
const client = new MongoClient('mongodb://localhost:27017');
await client.connect();
const db = client.db('myapp');
const collection = db.collection('users');
// Создание пользователя
await collection.insertOne({
name: 'John Doe',
email: 'john@example.com',
createdAt: new Date()
});
// Поиск пользователей
const users = await collection.find({}).toArray();
console.log(users);
await client.close();
}
main().catch(console.error);
Мониторинг и отладка
Для продакшена критично следить за производительностью:
# Просмотр текущих операций
db.currentOp()
# Статистика коллекции
db.users.stats()
# Профилирование медленных запросов
db.setProfilingLevel(1, {slowms: 100})
db.system.profile.find().sort({ts: -1}).limit(5)
# Планы выполнения запросов
db.users.find({email: "john@example.com"}).explain("executionStats")
Безопасность и аутентификация
# Создание административного пользователя
use admin
db.createUser({
user: "admin",
pwd: "strongpassword123",
roles: [{role: "userAdminAnyDatabase", db: "admin"}]
})
# Создание пользователя для конкретной базы данных
use myapp
db.createUser({
user: "appuser",
pwd: "apppassword123",
roles: [{role: "readWrite", db: "myapp"}]
})
# Включение аутентификации в mongod.conf
# security:
# authorization: enabled
Резервное копирование и восстановление
# Создание бэкапа
mongodump --db myapp --out /backup/
# Восстановление из бэкапа
mongorestore --db myapp /backup/myapp/
# Экспорт в JSON
mongoexport --db myapp --collection users --out users.json
# Импорт из JSON
mongoimport --db myapp --collection users --file users.json
Интересные факты и нестандартные применения
- GridFS для хранения файлов больше 16MB прямо в MongoDB
- Геопространственные запросы для поиска объектов по координатам
- Change Streams для реакции на изменения в реальном времени
- Atlas Search для полнотекстового поиска с поддержкой autocomplete
# Геопространственный запрос
db.places.createIndex({location: "2dsphere"})
db.places.find({
location: {
$near: {
$geometry: {type: "Point", coordinates: [-73.9667, 40.78]},
$maxDistance: 1000
}
}
})
# Change Stream
const changeStream = db.collection('users').watch();
changeStream.on('change', (change) => {
console.log('Change detected:', change);
});
Альтернативные решения
Если MongoDB не подходит, рассмотри:
- CouchDB – документо-ориентированная с HTTP API
- Amazon DynamoDB – управляемая NoSQL от AWS
- Cassandra – для больших данных с высокой доступностью
- Redis – для кеширования и простых структур данных
- PostgreSQL с JSONB – гибридное решение
Заключение и рекомендации
MongoDB – отличный выбор для проектов, где требуется гибкость схемы данных и быстрое горизонтальное масштабирование. Особенно хорошо подходит для:
- Системы управления контентом
- Каталоги товаров с разнообразными характеристиками
- Логирование и аналитика
- Прототипирование и MVP
- Микросервисные архитектуры
Не используй MongoDB для:
- Финансовых систем с жёсткими требованиями к консистентности
- Сложных отчётов с множественными JOIN
- Небольших проектов, где SQL проще
Помни: правильные индексы и понимание агрегации – это 80% успеха в работе с MongoDB. Обязательно тестируй производительность запросов на реальных данных и не забывай про мониторинг.
Полезные ссылки:
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.