Skip to content

terratensor/geomantic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GeoMantic

Микросервис для импорта и синхронизации данных GeoNames с Manticore Search. Обеспечивает быстрый полнотекстовый поиск по географическим объектам с поддержкой русской морфологии, геопоиск и иерархическую навигацию.

📋 Содержание

🚀 Возможности

1. Импорт данных GeoNames

  • Потоковая обработка больших TSV файлов (allCountries.txt 1.8GB)
  • Поддержка всех 19 полей оригинальной схемы
  • Сохранение пустых полей при последовательных табуляциях
  • Прогресс-бары для длительных операций

2. Полнотекстовый поиск

  • Русская морфология: lemmatize_ru_all (все формы слов)
  • Английская морфология: stem_enru (Porter stemmer)
  • Инфиксный поиск: min_infix_len=3
  • Точные формы: index_exact_words=1

3. Пространственные запросы

  • S2 геохеши двух типов:
    • uint64 для быстрых сравнений (>, <, =)
    • string для префиксного поиска (LIKE 'ebc%')
  • Настраиваемый уровень точности (по умолчанию 9: ~18 км)
  • Геопоиск через координаты (latitude/longitude)

4. Иерархия административного деления

  • Построение из hierarchy.txt (518k связей)
  • Дополнение из admin кодов (129k сопоставлений)
  • Защита от циклов и ограничение глубины
  • Материализованные пути для быстрой навигации (2.44M записей)

5. Альтернативные имена

  • 18.7M записей на разных языках
  • Поддержка preferred/short/colloquial/historic имен
  • Языковая фильтрация (ru, en, other)

6. Управление данными

  • Полная переиндексация
  • Инкрементальные обновления (готовится)
  • Очистка таблиц без удаления файлов (make drop-tables)

🏗 Архитектура

Проект следует гексагональной архитектуре (ports & adapters):

├── cmd/                    # Точки входа
│   ├── geomantic/         # Основной импортер
│   ├── build_hierarchy/   # Построение иерархии
│   ├── build_paths/       # Построение путей
│   └── drop_tables/       # Очистка таблиц
├── internal/
│   ├── core/              
│   │   ├── domain/        # Бизнес-модели
│   │   └── ports/         # Интерфейсы репозиториев
│   ├── adapters/          
│   │   ├── repositories/  # Manticore реализация
│   │   └── downloader/    # Скачивание файлов
│   ├── app/               
│   │   ├── services/      # Оркестрация
│   │   └── pipeline/      # Потоковая обработка
│   └── config/            # Конфигурация
└── pkg/                   # Общие утилиты

🔧 Технологии

  • Go 1.25.2+ - основной язык разработки
  • Manticore Search - поисковый движок
  • Docker & Docker Compose - контейнеризация
  • S2 Geometry - геопространственные вычисления
  • NDJSON - формат bulk операций

📦 Установка

# Клонировать репозиторий
git clone https://github.com/terratensor/geomantic.git
cd geomantic

# Инициализировать проект
make init

# Запустить Manticore
make docker-up

# Выполнить полный импорт
make import

# Построить иерархию
make hierarchy

# Построить материализованные пути
make paths

# Или всё сразу
make full

⚙️ Конфигурация

Файл .env:

# Manticore
MANTICORE_HOST=localhost
MANTICORE_PORT=9309
MANTICORE_TIMEOUT=30s

# Download
GEONAMES_BASE_URL=https://download.geonames.org/export/dump/
DOWNLOAD_TIMEOUT=10m
MAX_RETRIES=3

# Pipeline
BATCH_SIZE=1000
WORKERS_COUNT=4
CHANNEL_BUFFER_SIZE=10000

# S2 Geometry
S2_GEOHASH_LEVEL=9  # уровень точности геохеша (1-30)

# Import
DATA_DIR=./data
FULL_IMPORT=true
UPDATE_ENABLED=false

📊 Структура данных

Таблица geonames (13.4M записей)

id              bigint        # GeoNames ID
name            text          # Название (utf8)
asciiname       string        # ASCII название
alternatenames  text          # Альтернативные имена
latitude        float         # Широта
longitude       float         # Долгота
feature_class   string        # Класс объекта (A/H/L/P/R/S/T/U/V)
feature_code    string        # Код объекта
country_code    string        # Код страны (ISO-3166)
cc2             string        # Альтернативные коды стран
admin1_code     string        # Код адм. деления 1 уровня
admin2_code     string        # Код адм. деления 2 уровня
admin3_code     string        # Код адм. деления 3 уровня
admin4_code     string        # Код адм. деления 4 уровня
population      bigint        # Население
elevation       int           # Высота (метры)
dem             int           # Цифровая модель рельефа
timezone        string        # Часовой пояс (IANA)
modification_date timestamp    # Дата последнего изменения
parent_id       bigint        # ID родителя в иерархии
hierarchy_path  string        # Материализованный путь
full_text       text          # Сконкатенированные поля для поиска
geohash_int     bigint        # S2 геохеш (uint64) для фильтрации
geohash_string  string        # S2 геохеш (string) для префиксного поиска

Таблица alternate_names (18.7M записей)

id              bigint        # ID альтернативного имени
geonameid       bigint        # ID основного объекта
isolanguage     string        # Код языка (ISO 639)
alternatename   text          # Альтернативное имя
ispreferredname bool          # Предпочтительное имя
isshortname     bool          # Короткое имя
iscolloquial    bool          # Разговорное имя
ishistoric      bool          # Историческое имя
from_period     string        # Период использования (с)
to_period       string        # Период использования (по)
language_group  string        # Группа языка (ru/en/other)
is_official     bool          # Официальное имя

Таблица hierarchy (518k записей)

parent_id       bigint        # ID родителя
child_id        bigint        # ID потомка
relation_type   string        # Тип связи (ADM/amt/...)
is_admin        bool          # Административная связь
is_user_defined bool          # Пользовательская связь

Таблица admin_codes (129k записей)

id              bigint        # GeoNames ID
code            string        # Код адм. деления
name            text          # Название
ascii_name      string        # ASCII название
geoname_id      bigint        # GeoNames ID
level           int           # Уровень (1/2/5)
parent_code     string        # Код родителя

Таблица hierarchy_paths (2.44M записей)

geoname_id      bigint        # ID объекта
path            string        # Человекочитаемый путь
path_ids        string        # Путь из ID
depth           int           # Глубина вложенности
root_id         bigint        # ID корневого элемента

🔍 Примеры запросов

Полнотекстовый поиск

-- Поиск с русской морфологией
SELECT * FROM geonames 
WHERE MATCH('Моско́вский Кремль');

-- Поиск по альтернативным именам
SELECT name, alternate_names.alternatename   
FROM geonames   
INNER JOIN alternate_names ON alternate_names.geonameid = geonames.id   
WHERE MATCH('Moscow', alternate_names) AND alternate_names.isolanguage = 'en';

Геопоиск

-- Поиск в радиусе 10 км
SELECT name, geohash_string, uint64(geohash_int), GEODIST(40.7643929, -73.9997683, latitude, longitude, {in=deg, out=m}) 
AS distance  
FROM geonames  
WHERE distance < 10000  
ORDER BY distance ASC;



-- Поиск по геохешу (все объекты в одной ячейке)
SELECT name, geohash_string, uint64(geohash_int) 
FROM geonames  
WHERE geohash_int = -8520146389961801728;


-- Префиксный поиск по области
SELECT name, geohash_string, uint64(geohash_int) 
FROM geonames  
WHERE match('@geohash_string aac*');

Иерархия

-- Поиск через материализованные пути
SELECT name, hierarchy_paths.path  
FROM geonames 
INNER JOIN hierarchy_paths ON hierarchy_paths.geoname_id = geonames.id WHERE match('European\\/Russia\\/*');

-- Количество объектов по уровням
SELECT depth, COUNT(*)  
FROM hierarchy_paths  
GROUP BY depth  
ORDER BY depth ASC;

Аналитика

-- Топ-10 стран по количеству записей
SELECT country_code, COUNT(*) as cnt 
FROM geonames 
GROUP BY country_code 
ORDER BY cnt DESC 
LIMIT 10;

-- Распределение по типам объектов
SELECT feature_code, COUNT(*) as cnt 
FROM geonames 
GROUP BY feature_code 
ORDER BY cnt DESC 
LIMIT 20;

-- Группировка по геохешам для кластеризации
SELECT geohash_string, COUNT(*) 
FROM geonames 
GROUP BY geohash_string 
HAVING COUNT(*) > 100;

⚡ Производительность

Операция Время Записей
Импорт allCountries.txt ~20 мин 13.4M
Импорт alternateNamesV2.txt ~15 мин 18.7M
Построение иерархии ~13 мин 518k связей
Построение путей ~10 мин 2.44M путей
Полнотекстовый поиск <100 мс -
Геопоиск <50 мс -

📈 Планы развития

  • Базовый импорт данных
  • Поддержка русской морфологии
  • Иерархия административного деления
  • Материализованные пути
  • S2 геохеши
  • Инкрементальные обновления (modifications-*.txt)
  • REST API для поиска
  • Поддержка границ (shapes)
  • Кэширование популярных запросов
  • Мониторинг и метрики

📄 Лицензия

MIT

👥 Авторы

🙏 Благодарности

  • GeoNames - за предоставленные данные
  • Manticore Search - за отличный поисковый движок
  • S2 Geometry - за геопространственные алгоритмы

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors