Недавно я подготовил рабочий прототип проекта 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 - надёжное хранение структурированных справочников с поддержкой транзакций.

Как это работает?

Алгоритм рекомендаций

Система использует трёхэтапный подход:

  1. Фильтрация:

    • По региону и городу
    • По типу бизнеса (локация должна подходить для запрошенного типа)
  2. Ранжирование:

    • Traffic Score (0-10) - чем выше, тем лучше. Бустинг для локаций с score >= 7.0
    • Competition Density (0-10) - чем ниже, тем лучше. Бустинг для локаций с density <= 3.0
    • Демография - соответствие целевой аудитории (возраст, доход, интересы)
  3. Сортировка:

    • По релевантности (комбинированный 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) при необходимости

Что нужно улучшить и доработать

Студенты планируют доработать следующие аспекты:

  1. Фронтенд-часть - веб-интерфейс для визуализации рекомендаций и работы с данными
  2. Кэширование - добавить Redis для часто запрашиваемых рекомендаций
  3. ML-модели - использовать обученные модели для более точного ранжирования
  4. Real-time обновления - подписка на изменения через WebSocket
  5. Аналитика - сбор метрик использования API и визуализация данных
  6. A/B тестирование - сравнение разных алгоритмов ранжирования
  7. Расширенная аналитика - более глубокий анализ бизнес-среды

Эти доработки желаемы, но не являются обязательством ребят. Они сделают то, что считают необходимым в рамках работы. Прототип, который мы сделали уже содержит значительную базу

Выводы

Проект показал, что комбинация Go + OpenSearch + PostgreSQL - мощный инструмент для построения рекомендательных систем. Особенно ценна возможность:

  • Быстро прототипировать идеи
  • Легко масштабировать решение
  • Автоматизировать документацию
  • Деплоить через Docker

Работа над проектом продолжается: студенты развивают систему, добавляют фронтенд и расширяют функциональность. Это отличный пример того, как можно совместить академическую работу с практической реализацией реальной задачи.

Код открыт и доступен на GitHub. Буду рад вопросам и предложениям по улучшению!


Полезные ссылки: