Автор статьи: Сергей Прощаев (@sproshchaev)
Руководитель направления Java-разработки в FinTech
В мире разработки часто возникает соблазн использовать знакомый инструмент для всех задач. Зачем изучать что-то новое, если есть проверенная реляционная база данных (РСУБД), такая как PostgreSQL или MySQL? Однако, когда дело доходит до реализации мощного, быстрого и релевантного поиска, этот подход терпит неудачу.
Elasticsearch — это не просто база данных, это распределенный поисковый и аналитический движок. В этой статье мы проведем детальное сравнение Elasticsearch и реляционных баз данных, разберемся в их архитектурных различиях и определим, когда каждый из инструментов становится титаном в своей нише.
Чтобы статья была максимально практико-ориентированной, мы рассмотрим, как с помощью Spring Boot быстро поднять приложение с интегрированным Elasticsearch и реализовать поиск, который «летает».
Что такое Реляционная База Данных и ее сильные стороны?
Реляционные базы данных, такие как PostgreSQL, MySQL или Oracle, — это основа большинства приложений. Они основаны на строгой, предопределенной схеме данных, организованной в виде таблиц, строк и столбцов.
Сильные стороны РСУБД:
Транзакции и целостность данных (ACID): Гарантированная согласованность данных, что критически важно для финансовых операций, заказов и т.д.
Сложные запросы и JOINs: Мощный язык SQL позволяет выполнять сложные связи между таблицами и агрегации.
Строгая схема: Четкая структура данных предотвращает появление «мусора» и обеспечивает целостность.
Проверенная надежность: Технологии, отточенные десятилетиями.
РСУБД — это титан для задач, где важна точность, консистентность и сложность запросов.
Что такое Elasticsearch и когда он незаменим?
Elasticsearch — это не база данных в классическом понимании. Это распределенный, JSON-ориентированный поисковый движок, построенный на основе Apache Lucene.
Сильные стороны Elasticsearch:
Молниеносный полнотекстовый поиск: Умный поиск по смыслу, а не по точному совпадению. Учет морфологии, синонимов и даже опечаток.
Масштабируемость: Горизонтальное масштабирование «из коробки». Просто добавьте новый сервер в кластер.
Гибкая схема (Schema-less): Можно быстро добавлять новые поля без миграций базы данных.
Мощная аналитика в реальном времени: Встроенные агрегации для построения сложных отчетов и дашбордов.
Elasticsearch — это титан для задач, где важна скорость поиска, анализ больших объемов текста и масштабируемость.
Сравнение Elasticsearch и РСУБД: подробный анализ
На Рис. 1 изображены принципиальные архитектурные различия двух подходов к хранению и обработке данных.

Архитектура и модель данных
Давайте рассмотрим различия в основных концепциях.
РСУБД: Данные хранятся в нормализованных таблицах. Связи между ними устанавливаются через внешние ключи. Для выборки данных из нескольких таблиц необходим оператор JOIN.
Elasticsearch: Данные хранятся в виде денормализованных JSON-документов в индексах. Каждый документ самодостаточен. JOIN-ы поддерживаются, но не являются сильной стороной и могут негативно влиять на производительность.
Схема данных
РСУБД: Строгая схема (Schema-first). Перед началом работы необходимо определить таблицы, столбцы, типы данных и связи. Любое изменение схемы требует выполнения миграций (ALTER TABLE).
Elasticsearch: Гибкая схема (Schema-less / Schema-on-read). Вы можете отправить JSON-документ, и Elasticsearch попытается автоматически определить типы полей. Для продакшена рекомендуется определять схему (mapping) вручную для оптимальной производительности.
Язык запросов
РСУБД: Мощный и стандартизированный SQL. Позволяет выполнять чрезвычайно сложные запросы с множественными JOIN, подзапросами и оконными функциями.
Elasticsearch: Используется собственный JSON-based Query DSL. Идеально подходит для построения сложных поисковых запросов, фильтрации и агрегаций, но имеет более крутую кривую обучения по сравнению с SQL.
Производительность и масштабируемость
РСУБД: Традиционно масштабируются вертикально (увеличение мощности сервера). Горизонтальное масштабирование (шардирование, репликация) возможно, но является сложной задачей. Высокая производительность на сложных JOIN-запросах и транзакциях.
Elasticsearch: Изначально спроектирован для горизонтального масштабирования. Индекс автоматически делится на шарды, которые распределяются по узлам кластера. Это обеспечивает невероятную производительность на операциях поиска и аналитики, особенно при больших объемах данных.
Практический пример: Реализация поиска на Spring Boot + Elasticsearch
Давайте посмотрим, как быстро можно реализовать мощный поиск в вашем Java-приложении. Мы создадим демо-приложение для управления персонами с полнотекстовым поиском.
Архитектура приложения:
Spring Boot REST API
Spring Data Elasticsearch
Документ-ориентированная модель данных
Готовые поисковые endpoints
Ключевые зависимости в pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Базовая конфигурация в application.properties:
spring.elasticsearch.rest.uris=http://localhost:9200
spring.data.elasticsearch.repositories.enabled=true
Модель данных Person:
@Document(indexName = "persons")
public class Person {
@Id
private String id;
@Field(type = FieldType.Text, analyzer = "standard")
private String firstName;
@Field(type = FieldType.Text, analyzer = "standard")
private String lastName;
@Field(type = FieldType.Integer)
private Integer age;
@Field(type = FieldType.Text, analyzer = "standard")
private String profession;
@Field(type = FieldType.Keyword)
private String city;
@Field(type = FieldType.Text, analyzer = "standard")
private String bio;
}
Обратите внимание нааннотации @Field — здесь мы явно указываем типы полей для оптимального поиска. Поле city имеет тип Keyword для точного поиска, а текстовые поля используют анализатор для полнотекстового поиска.
Репозиторий с поисковыми методами:
public interface PersonRepository extends ElasticsearchRepository<Person, String> {
List<Person> findByFirstName(String firstName);
List<Person> findByAgeBetween(Integer minAge, Integer maxAge);
List<Person> findByCity(String city);
List<Person> findByBioContaining(String text);
List<Person> findByCityAndAgeGreaterThan(String city, Integer age);
}
Spring Data Elasticsearch автоматически генерирует реализации этих методов — вам не нужно писать код запросов вручную!
REST API endpoints:
POST /api/persons — создание персоны
GET /api/persons/search/city?city=New York — точный поиск по городу
GET /api/persons/search/age‑range?min=25&max=35 — поиск по диапазону
GET /api/persons/search/bio?text=java — полнотекстовый поиск в биографии
GET /api/persons/search/global?q=developer — глобальный поиск по всем текстовым полям
Что делает этот пример особенным?
Автоматическая индексация — при сохранении через репозиторий данные сразу становятся доступны для поиска
Разные типы поиска — от точного match до полнотекстового с анализом текста
Готовый REST API — можно сразу интегрировать с фронтендом
Автогенерация ID — Elasticsearch сам создает уникальные идентификаторы
Логирование запросов — для отладки можно включить TRACE уровень логирования
Пример использования:
# Создание персоны
curl -X POST http://localhost:8080/api/persons \
-H "Content-Type: application/json" \
-d '{"firstName":"John","lastName":"Doe","age":30,"profession":"Developer","city":"New York","bio":"Java developer with Spring Boot experience"}'
# Полнотекстовый поиск
curl "http://localhost:8080/api/persons/search/bio?text=java"
# Комбинированный поиск
curl "http://localhost:8080/api/persons/search/city-age?city=New%20York&age=25"
Полный код приложения с Docker-конфигурацией и дополнительными примерами сложных запросов доступен в репозитории GitHub: https://github.com/sproshchaev/elasticsearch-demo/tree/base
Этот пример показывает, как за 30-40 минут можно создать полнофункциональное приложение с мощным поиском, который действительно "летает", используя Spring Boot и Elasticsearch.
Рекомендации по выбору: Титан для своей задачи
Выбирайте Реляционную Базу Данных, если:
Ваши данные сильно нормализованы и требуют сложных JOIN.
Критически важны транзакции и гарантированная целостность данных (ACID).
Структура данных стабильна и редко меняется.
Выбирайте Elasticsearch, если:
Ваша основная задача — быстрый и релевантный поиск по большим объемам текста.
Вам нужны мощные возможности аналитики и агрегации в реальном времени.
Вы работаете с большими данными и вам необходимо горизонтальное масштабирование.
Ваша схема данных гибкая и может часто меняться.
Заключение
Elasticsearch и реляционные базы данных — не конкуренты, а мощные союзники в арсенале современного разработчика. РСУБД — это титан систем управления, надежности и транзакций. Elasticsearch — это титан поиска, аналитики и масштабируемости.
Правильная архитектура часто подразумевает их совместное использование: данные создаются и хранятся с гарантией целостности в РСУБД, а затем асинхронно копируются в Elasticsearch для организации молниеносного и интеллектуального поиска. Понимание сильных и слабых сторон каждого инструмента позволяет строить эффективные, производительные и масштабируемые системы, отвечающие любым бизнес-требованиям.

Если хотите копнуть глубже, чем простая интеграция с Elasticsearch, курс Java Developer. Professional разбирает JVM, многопоточность, современные подходы к архитектуре и работе со стеком, чтобы осознанно выбирать инструменты и компромиссы. Много практики, жёсткое код-ревью и задачи уровня уверенного middle.
Чтобы узнать больше о формате обучения и познакомиться с преподавателями — записывайтесь на бесплатный демо-урок «Что такое Scoped Values» 16 декабря в 20:00. В результате поймете назначение Scoped Values и базовые сценарии применения, сможете написать минимальный пример в Java 25. >> Записаться на урок
Комментарии (6)

SolidSnack
11.12.2025 06:34Мде, руководитель разработки в финтехе не знает про полнотекстовый поиск в pg и документацию? Если честно статья ахинея как по мне)

silvercaptain
11.12.2025 06:34Последний "писк моды" использование AI как агента для полнотестового поиска. (последняя версяи SQL Server'a именно про это)
Мне кажется, что эра Поисковых движков, катится к закату и не только в разрезе баз данных, но и глобально. Я вот ловлю себя на мысли, что все реже использую Google и все чаще какой-то AI для того, что бы найти нужную мне информацию

botflow
11.12.2025 06:34Отличная, очень толковая и сбалансированная статья — как раз то, что нужно middle-разработчикам, которые уже «переросли» простые CRUD-приложения и начинают сталкиваться с реальными проблемами поиска.
Особенно ценно, что вы не скатились в типичный холивар «Elasticsearch лучше PostgreSQL» или наоборот, а чётко показали: это инструменты для разных задач. Абзац в конце про совместное использование — чистая правда жизни. В 90 % серьёзных проектов, где я работал последние 5–7 лет, именно так и делается:
PostgreSQL — источник правды (source of truth) + транзакции
Elasticsearch — вторичный индекс для поиска, автокомплита, аналитики и дашбордов
Синхронизация через CDC (Debezium), Logstash, или самописный outbox-паттерн
К небольшому дополнению от практикующего:
Сейчас в Spring Boot 3 + Spring Data Elasticsearch 5+ лучше сразу переходить на новый Elasticsearch Java Client (не на устаревший RestHighLevelClient). В вашем примере используется старый spring-boot-starter-data-elasticsearch, который внутри всё ещё тянет High-Level Client и помечен как deprecated. Для новых проектов рекомендую:
XML
<dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>и конфигурацию через ElasticsearchClient bean.
В продакшене почти всегда нужно явно задавать mapping и settings индекса (количество шардов, реплик, свои анализаторы, нормалайзеры). Автоматический mapping очень часто «угадывает» неправильно и потом приходится делать болезненный reindex.
Для полнотекстового поиска по-русски стандартный анализатор работает плохо. Стоит сразу подключать русский морфологический плагин или хотя бы использовать встроенный hunspell + свой словарь синонимов.
В остальном — пример идеально показывает, насколько быстро можно получить работающий и очень приличный поиск. За те же 30–40 минут на чистом PostgreSQL с GIN-индексами и ts_vector вы получите что-то в 10–50 раз медленнее и без ранжирования по релевантности.
Спасибо за статью и за ссылку на репозиторий — обязательно покажу команде как эталонный «быстрый старт».
beswalod
Hi, ChatGPT. Please write an article for Habr.com about Elasticsearch for beginners...
gotch
Какой вообще смысл сравнивать хранилище json документов и традиционную реляционную СУБД.
Tishka17
Если не сравнить, кто-то подумает что это одно и тоже и начнет юзать эластик как основную бд.