Настройка базы данных MongoDB для веб-приложения

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Настройка базы данных MongoDB для веб-приложения
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Настройка базы данных MongoDB для веб-приложения

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

Установка MongoDB 7.0

# Ubuntu 22.04 / 24.04
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg
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" > /etc/apt/sources.list.d/mongodb-org-7.0.list
apt update && apt install -y mongodb-org
systemctl enable mongod && systemctl start mongod

Первоначальная настройка безопасности:

// mongosh
use admin
db.createUser({
  user: "admin",
  pwd: "strong_admin_password",
  roles: ["root"]
})

// Создать пользователя приложения
use myapp
db.createUser({
  user: "myapp",
  pwd: "app_password",
  roles: [{ role: "readWrite", db: "myapp" }]
})

/etc/mongod.conf

net:
  port: 27017
  bindIp: 127.0.0.1  # только localhost; для репликации — указать IP

security:
  authorization: enabled

storage:
  dbPath: /var/lib/mongodb
  wiredTiger:
    engineConfig:
      cacheSizeGB: 2  # 50% доступной RAM для WiredTiger кэша

operationProfiling:
  slowOpThresholdMs: 100
  mode: slowOp

replication:
  replSetName: "rs0"  # включить если нужна репликация

Индексы

// Основные индексы — создавать сразу при проектировании
db.users.createIndex({ email: 1 }, { unique: true, background: true })
db.orders.createIndex({ userId: 1, createdAt: -1 })
db.orders.createIndex({ status: 1, createdAt: -1 })

// Частичный индекс — только активные документы
db.sessions.createIndex(
  { userId: 1, expiresAt: 1 },
  { partialFilterExpression: { revokedAt: { $exists: false } } }
)

// TTL-индекс — автоудаление устаревших документов
db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 })  // 30 дней

// Текстовый поиск
db.articles.createIndex({ title: "text", body: "text" }, { default_language: "russian" })

// Compound wildcard для каталога с произвольными атрибутами
db.products.createIndex({ "attributes.$**": 1 })

Aggregation Pipeline

Мощный инструмент для аналитики прямо в базе:

// Выручка по категориям за период
db.orders.aggregate([
  {
    $match: {
      createdAt: { $gte: ISODate("2024-01-01"), $lt: ISODate("2024-04-01") },
      status: "paid"
    }
  },
  { $unwind: "$items" },
  {
    $lookup: {
      from: "products",
      localField: "items.productId",
      foreignField: "_id",
      as: "product"
    }
  },
  { $unwind: "$product" },
  {
    $group: {
      _id: "$product.category",
      revenue: { $sum: { $multiply: ["$items.price", "$items.quantity"] } },
      orders: { $addToSet: "$_id" }
    }
  },
  {
    $project: {
      category: "$_id",
      revenue: { $round: ["$revenue", 2] },
      orderCount: { $size: "$orders" }
    }
  },
  { $sort: { revenue: -1 } }
])

Replica Set

// mongosh на одном из узлов
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo1:27017", priority: 2 },
    { _id: 1, host: "mongo2:27017", priority: 1 },
    { _id: 2, host: "mongo3:27017", priority: 0, hidden: true, votes: 0 }
    // третий узел — скрытый для бэкапов, не участвует в выборах
  ]
})

// Проверка статуса
rs.status()

Connection string приложения с failover:

mongodb://myapp:password@mongo1:27017,mongo2:27017/myapp?replicaSet=rs0&readPreference=secondaryPreferred&w=majority

Mongoose (Node.js)

import mongoose, { Schema, Document } from 'mongoose'

interface IProduct extends Document {
  sku: string
  name: string
  category: string
  price: number
  attributes: Record<string, unknown>
  createdAt: Date
}

const productSchema = new Schema<IProduct>({
  sku: { type: String, required: true, unique: true, index: true },
  name: { type: String, required: true },
  category: { type: String, required: true, index: true },
  price: { type: Number, required: true, min: 0 },
  attributes: { type: Schema.Types.Mixed, default: {} }
}, {
  timestamps: true,
  toJSON: { virtuals: true }
})

productSchema.index({ name: 'text', 'attributes.description': 'text' })

export const Product = mongoose.model<IProduct>('Product', productSchema)

// Запрос с пагинацией
export async function listProducts(category: string, page = 1, limit = 24) {
  const skip = (page - 1) * limit
  const [items, total] = await Promise.all([
    Product.find({ category }).sort({ createdAt: -1 }).skip(skip).limit(limit).lean(),
    Product.countDocuments({ category })
  ])
  return { items, total, pages: Math.ceil(total / limit) }
}

Резервное копирование

# mongodump — логический бэкап
mongodump --uri="mongodb://myapp:password@localhost:27017/myapp" \
  --gzip --archive=/backup/myapp_$(date +%Y%m%d).archive

# Восстановление
mongorestore --uri="mongodb://admin:password@localhost:27017" \
  --gzip --archive=/backup/myapp_20240315.archive

# mongodump одной коллекции
mongodump --uri="..." --collection=orders --query='{"createdAt":{"$gte":{"$date":"2024-01-01T00:00:00Z"}}}'

Сроки

Установка с replica set, настройка индексов под конкретную схему: 1–2 дня. Шардирование большого кластера с балансировкой данных: 3–5 дней. Миграция с реляционной БД с трансформацией схемы: 1–3 недели в зависимости от сложности доменной модели.