Недавно я подготовил рабочий прототип проекта go_es_analytical_system - рекомендательной системы для поиска и анализа локаций для различных типов бизнеса. Здесь es в названии появилось из-за того, что я плинировал Elasticsearch, но при разработке возникли сложности при получении соответствующего контейнера, поэтому в итоге используется OpenSearch.
Важный момент: идея проекта принадлежит моим студентам, которые выбрали себе тему магистерской диссертации “Разработка приложения для анализа бизнес-среды и выдачи рекомендаций по старту бизнеса”. Да, одну на двоих. Сейчас это допустимо в рамках продолжения работ по дисциплине “Проектная деятельность”. У них была готова концепция и понимание, что нужно решить, а я предложил технологии и реализацию. Умение качественно оформить свои идеи привело к утверждению темы и к созданию данного прототипа. Я подготовил текущий рабочий прототип, а они будут дорабатывать систему, создавать фронтенд-часть и расширять функциональность.
Хочу поделиться опытом и рассказать, какие задачи решает эта система и какие технологии было решено использовать.
Зачем это нужно?
Представьте ситуацию: вы хотите открыть кафе, ресторан или магазин. Где лучше разместить бизнес? Какие факторы учесть?
- Трафик - сколько людей проходит мимо локации
- Конкуренция - сколько похожих заведений уже есть рядом
- Демография - кто живёт и работает в этом районе
- Доступность - удобно ли добираться
Ручной анализ таких данных занимает недели. Система делает это за секунды, используя комбинацию PostgreSQL для справочников и OpenSearch для полнотекстового поиска и ранжирования.
Архитектура решения
Технологический стек
- Go - основной язык разработки
- OpenSearch - поиск и ранжирование локаций
- PostgreSQL - хранение справочников (типы бизнеса, регионы)
- Docker Compose - оркестрация сервисов
- Swagger/OpenAPI - автоматическая документация API
Почему именно такой стек?
Go - быстро, без зависимостей, один бинарник, умею. Идеально для микросервисов и CI/CD.
OpenSearch - открытый поисковый движок, форк Elasticsearch, с поддержкой:
- Геопространственных запросов (geo_point)
- Векторного поиска (dense_vector для kNN)
- Полнотекстового поиска
- Гибкого ранжирования
- Полная совместимость с Elasticsearch API
Выбор OpenSearch вместо Elasticsearch был сделан по нескольким причинам:
- Открытая лицензия (Apache 2.0)
- Нет проблем с доступом к образам Docker
- Активное развитие сообществом
- Совместимость с существующими инструментами
PostgreSQL - надёжное хранение структурированных справочников с поддержкой транзакций.
Как это работает?
Алгоритм рекомендаций
Система использует трёхэтапный подход:
Фильтрация:
- По региону и городу
- По типу бизнеса (локация должна подходить для запрошенного типа)
Ранжирование:
- Traffic Score (0-10) - чем выше, тем лучше. Бустинг для локаций с score >= 7.0
- Competition Density (0-10) - чем ниже, тем лучше. Бустинг для локаций с density <= 3.0
- Демография - соответствие целевой аудитории (возраст, доход, интересы)
Сортировка:
- По релевантности (комбинированный score)
- По traffic_score (по убыванию)
- По competition_density (по возрастанию)
Структура данных в OpenSearch
{
"id": "loc_1",
"name": "Локация 1",
"address": "ул. Примерная, д. 10, Москва",
"coordinates": {
"lat": 55.7558,
"lon": 37.6173
},
"region": "Москва",
"city": "Москва",
"business_types_suitable": ["cafe", "restaurant"],
"traffic_score": 8.5,
"competition_density": 2.3,
"demographics": {
"age_group": "26-35",
"average_income": 75000,
"interests": ["food", "technology"],
"population_density": 5000
},
"embedding": [0.1, 0.2, ...] // 128-мерный вектор для kNN
}
API и использование
Основные эндпоинты
POST /locations/recommend - получить рекомендации:
curl -X POST http://localhost:8080/locations/recommend \
-H "Content-Type: application/json" \
-d '{
"region": "Москва",
"city": "Москва",
"business_type": "cafe",
"limit": 20
}'
GET /locations/{id} - детали локации
GET /business-types - список типов бизнеса
GET /regions - список регионов
Автоматическая документация
Проект использует swaggo/swag для генерации OpenAPI документации из комментариев в коде:
make swagger
# Открыть http://localhost:8080/swagger/index.html
Это экономит время на поддержке документации - она всегда актуальна.
Запуск и разработка
Быстрый старт с Docker
# Запуск всех сервисов
docker-compose up -d
# Индексация тестовых данных
docker-compose exec app ./indexer
Система запускает:
- OpenSearch на порту 9200
- OpenSearch Dashboards на порту 5601
- PostgreSQL на порту 5432
- Go приложение на порту 8080
Локальная разработка
# Запуск только БД и OpenSearch
docker-compose up -d opensearch postgres
# Установка зависимостей
go mod download
# Запуск сервера
go run cmd/server/main.go
# Индексация данных
go run cmd/indexer/main.go
Решённые проблемы
1. Выбор поискового движка
Изначально рассматривался Elasticsearch, но при работе с официальными образами иногда возникают проблемы с доступом (403 ошибки). Поэтому был выбран OpenSearch - открытый форк Elasticsearch, который:
- Полностью совместим с Elasticsearch API
- Имеет открытую лицензию Apache 2.0
- Не имеет проблем с доступом к образам Docker
- Активно развивается сообществом
2. Производительность поиска
Для ускорения поиска используется:
- Геопространственные индексы для координат
- Векторные индексы для семантического поиска
- Бустинг релевантных локаций в ранжировании
3. Масштабируемость
Архитектура позволяет:
- Горизонтально масштабировать OpenSearch
- Использовать read replicas для PostgreSQL
- Добавлять кэширование (Redis) при необходимости
Что нужно улучшить и доработать
Студенты планируют доработать следующие аспекты:
- Фронтенд-часть - веб-интерфейс для визуализации рекомендаций и работы с данными
- Кэширование - добавить Redis для часто запрашиваемых рекомендаций
- ML-модели - использовать обученные модели для более точного ранжирования
- Real-time обновления - подписка на изменения через WebSocket
- Аналитика - сбор метрик использования API и визуализация данных
- A/B тестирование - сравнение разных алгоритмов ранжирования
- Расширенная аналитика - более глубокий анализ бизнес-среды
Эти доработки желаемы, но не являются обязательством ребят. Они сделают то, что считают необходимым в рамках работы. Прототип, который мы сделали уже содержит значительную базу
Выводы
Проект показал, что комбинация Go + OpenSearch + PostgreSQL - мощный инструмент для построения рекомендательных систем. Особенно ценна возможность:
- Быстро прототипировать идеи
- Легко масштабировать решение
- Автоматизировать документацию
- Деплоить через Docker
Работа над проектом продолжается: студенты развивают систему, добавляют фронтенд и расширяют функциональность. Это отличный пример того, как можно совместить академическую работу с практической реализацией реальной задачи.
Код открыт и доступен на GitHub. Буду рад вопросам и предложениям по улучшению!
Полезные ссылки: