← Назад к вопросам

Что такое MongoDB?

2.3 Middle🔥 121 комментариев
#SOLID и паттерны проектирования#Spring Boot и Spring Data

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

MongoDB: NoSQL база данных

MongoDB — это документоориентированная NoSQL база данных, которая хранит данные в формате JSON-подобных документов вместо традиционных таблиц с строками и столбцами. MongoDB очень популярна в современной разработке благодаря гибкости и простоте использования.

Основные характеристики

1. Документоориентированная структура

МонгоDB хранит данные в BSON документах (Binary JSON) вместо строк таблиц:

// Пример документа MongoDB
{
    "_id": ObjectId("507f1f77bcf86cd799439011"),
    "name": "John Doe",
    "email": "john@example.com",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "New York",
        "zipCode": "10001"
    },
    "hobbies": ["reading", "gaming", "cooking"],
    "createdAt": ISODate("2024-01-15T10:30:00Z")
}

Каждый документ имеет уникальный идентификатор _id (аналог первичного ключа).

2. Гибкая схема

У документов в одной коллекции может быть РАЗНАЯ структура:

// Коллекция "users" может содержать:
// Документ 1
{ "name": "Alice", "age": 25, "email": "alice@example.com" }

// Документ 2 (другая структура!)
{ "name": "Bob", "phone": "+1-234-567-8900" }

// Документ 3
{ "name": "Charlie", "age": 35, "address": { "city": "Boston" }, "premium": true }

Это контрастирует с SQL базами, где все строки в таблице имеют одинаковую структуру.

Терминология: SQL vs MongoDB

SQLMongoDB
DatabaseDatabase
TableCollection
RowDocument
ColumnField
Primary KeyObjectId (_id)
IndexIndex
JoinEmbedded documents / Aggregation

Работа с MongoDB из Java

1. Подключение через MongoDB Driver

import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoCollection;
import org.bson.Document;

public class MongoDBExample {
    public static void main(String[] args) {
        // Подключение к MongoDB
        MongoClient mongoClient = new MongoClient("localhost", 27017);
        MongoDatabase database = mongoClient.getDatabase("myapp");
        MongoCollection<Document> collection = database.getCollection("users");
        
        // Закрытие соединения
        mongoClient.close();
    }
}

2. CRUD операции

import com.mongodb.client.MongoCollection;
import org.bson.Document;

public class UserDAO {
    private MongoCollection<Document> collection;
    
    // CREATE - вставка нового документа
    public void insertUser(String name, String email, int age) {
        Document user = new Document()
            .append("name", name)
            .append("email", email)
            .append("age", age)
            .append("createdAt", new Date());
        
        collection.insertOne(user);
    }
    
    // READ - чтение документа
    public Document findUser(String email) {
        return collection.find(
            new Document("email", email)
        ).first();
    }
    
    // UPDATE - обновление документа
    public void updateUser(String email, String newName) {
        collection.updateOne(
            new Document("email", email),
            new Document("$set", new Document("name", newName))
        );
    }
    
    // DELETE - удаление документа
    public void deleteUser(String email) {
        collection.deleteOne(
            new Document("email", email)
        );
    }
}

3. Spring Data MongoDB (рекомендуется)

Для работы с MongoDB в Spring приложениях используй Spring Data MongoDB:

import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.repository.MongoRepository;

// Модель документа
@Document(collection = "users")
public class User {
    @Id
    private String id;
    private String name;
    private String email;
    private int age;
    private LocalDateTime createdAt;
    
    // getters, setters
}

// Repository (как JPA для MongoDB)
public interface UserRepository extends MongoRepository<User, String> {
    User findByEmail(String email);
    List<User> findByAgeGreaterThan(int age);
}

// Использование в Service
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public User createUser(String name, String email, int age) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        user.setAge(age);
        return userRepository.save(user);
    }
    
    public User getUserByEmail(String email) {
        return userRepository.findByEmail(email);
    }
    
    public List<User> getAdults() {
        return userRepository.findByAgeGreaterThan(18);
    }
}

Запросы в MongoDB

// Фильтрация
Collection<Document> users = collection.find(
    new Document("age", new Document("$gte", 18))
).into(new ArrayList<>());

// Сортировка
collection.find().sort(
    new Document("createdAt", -1)
).into(new ArrayList<>());

// Ограничение результатов
collection.find().limit(10).into(new ArrayList<>());

// Проекция (выбор нужных полей)
collection.find().projection(
    new Document("name", 1).append("email", 1)
).into(new ArrayList<>());

Встроенные документы (Embedding)

МонгоDB позволяет вложить документы друг в друга:

// Документ с встроенным адресом
{
    "_id": ObjectId("..."),
    "name": "John",
    "address": {  // Встроенный документ
        "street": "123 Main St",
        "city": "New York",
        "zipCode": "10001"
    }
}
@Document(collection = "users")
public class User {
    @Id
    private String id;
    private String name;
    private Address address;  // Встроенный объект
}

public class Address {
    private String street;
    private String city;
    private String zipCode;
}

Связи между документами (References)

Альтернатива embedding - ссылки на другие документы:

// Документ "orders"
{
    "_id": ObjectId("..."),
    "orderDate": ISODate("2024-01-15"),
    "userId": ObjectId("507f1f77bcf86cd799439011"),  // Ссылка на user
    "amount": 150.00
}
@Document(collection = "orders")
public class Order {
    @Id
    private String id;
    @DBRef  // Ссылка на другой документ
    private User user;
    private LocalDateTime orderDate;
    private Double amount;
}

Агрегация (Aggregation Pipeline)

Мощный способ обработки данных:

List<Document> results = collection.aggregate(Arrays.asList(
    new Document("$match", new Document("age", new Document("$gte", 18))),
    new Document("$group", 
        new Document("_id", "$city")
        .append("count", new Document("$sum", 1))
        .append("avgAge", new Document("$avg", "$age"))
    ),
    new Document("$sort", new Document("count", -1))
)).into(new ArrayList<>());

Индексы

// Создание индекса для ускорения поиска
collection.createIndex(new Document("email", 1));

// Уникальный индекс
collection.createIndex(
    new Document("email", 1),
    new IndexOptions().unique(true)
);

// Составной индекс
collection.createIndex(
    new Document("name", 1).append("age", -1)
);

SQL vs MongoDB: Когда использовать?

ПараметрSQLMongoDB
Структура данныхЖёсткая схемаГибкая схема
МасштабируемостьВертикальнаяГоризонтальная
Сложные связиХорошоПлохо (нужны joins)
Изменяющиеся данныеСложно менять структуруЛегко
Большие объёмыGoodExcellent
ТранзакцииACID (4.0+)ACID (4.0+)
Скорость разработкиМедленнееБыстрее

Лучшие практики

  1. Используй правильный тип хранения

    • Embedding для часто используемых данных вместе
    • References для независимых сущностей
  2. Создавай индексы

    collection.createIndex(new Document("email", 1));
    
  3. Валидируй данные

    @NotNull
    private String name;
    
    @Email
    private String email;
    
  4. Используй Spring Data MongoDB вместо низкоуровневого API

  5. Думай о денормализации

    • MongoDB поощряет денормализацию для производительности
    • Избегай жёсткой нормализации как в SQL

Шардирование (Scalability)

МонгоDB автоматически распределяет данные между серверами:

// Настройка шардирования
sh.shardCollection("myapp.users", { "_id": "hashed" })

Транзакции (с 4.0+)

ClientSession session = mongoClient.startSession();
try {
    session.startTransaction();
    
    collection1.insertOne(session, document1);
    collection2.insertOne(session, document2);
    
    session.commitTransaction();
} finally {
    session.endSession();
}

Итого

  • MongoDB — документоориентированная NoSQL БД
  • Гибкая схема — документы могут иметь разную структуру
  • Встроенные документы — хорошо для денормализации
  • Масштабируемость — горизонтальная масштабируемость через шардирование
  • Java интеграция — используй Spring Data MongoDB
  • Идеальна для — быстро развивающихся приложений с меняющейся структурой данных