27 ноября 2025 г.
Структура
Создаём следующую структуру:
- docker-compose.yml
- manticore/
Docker Compose файл
Напишем следующий docker-compose.yml:
services:
manticore:
image: manticoresearch/manticore:latest
container_name: manticore-search
ports:
- "9306:9306" # MySQL protocol
- "9308:9308" # HTTP protocol
- "9312:9312" # Binary protocol
volumes:
- ./manticore/data:/var/lib/manticore
- ./manticore/log:/var/log/manticore
- ./manticore/config/manticore.conf:/etc/manticoresearch/manticore.conf
- ./manticore/run:/var/run/manticore
environment:
- EXTRA=1
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
restart: unless-stopped
networks:
- manticore-net
networks:
manticore-net:
driver: bridge
Базовая настройка
Основной конфигурационный файл (/etc/manticoresearch/manticore.conf)
searchd {
listen = 0.0.0.0:9312
listen = 0.0.0.0:9306:mysql
listen = 0.0.0.0:9308:http
log = /var/log/manticore/searchd.log
query_log = /var/log/manticore/query.log
pid_file = /var/run/manticore/searchd.pid
query_log_format = sphinxql
}
indexer {
mem_limit = 128M
}
common {
plugin_dir = /usr/lib/manticore
}
Далее можно сделать запуск контейнера:
docker-compose up -d
Создание индексов и заполнение данными
Конфигурация индекса (добавим в manticore.conf):
index products {
type = rt
path = /var/lib/manticore/products
rt_field = title
rt_field = description
rt_attr_string = category
rt_attr_uint = price
rt_attr_timestamp = created_at
rt_attr_multi = tags
min_infix_len = 3
expand_keywords = 1
}
И сделаем перезапуск контейнера:
docker-compose restart
Заполнение данными через MySQL протокол
Подключение:
mysql -P 9306 -h 127.0.0.1
Вставка данных:
INSERT INTO products (id, title, description, category, price, created_at, tags)
VALUES
(1, 'Смартфон Samsung Galaxy', 'Новый флагманский смартфон с отличной камерой', 'electronics', 59990, 1701388800, (1, 2, 3)),
(2, 'Ноутбук ASUS ZenBook', 'Ультрабук с процессором Intel Core i7', 'computers', 89990, 1701388800, (4, 5)),
(3, 'Наушники Sony WH-1000XM4', 'Беспроводные наушники с шумоподавлением', 'audio', 24990, 1701388800, (6, 7));
Пакетная вставка:
INSERT INTO products (id, title, description, category, price, tags) VALUES
(4, 'Мышь Logitech MX Master', 'Эргономичная беспроводная мышь', 'computers', 8990, (8)),
(5, 'Клавиатура Mechanical', 'Механическая клавиатура с RGB подсветкой', 'computers', 12990, (9, 10));
Заполнение через HTTP API
Вставка одной записи:
curl -X POST http://localhost:9308/json/insert \
-H "Content-Type: application/json" \
-d '{
"index":"products",
"id": 6,
"doc": {
"title": "Планшет Apple iPad Air",
"description": "Мощный планшет для работы и творчества",
"category": "tablets",
"price": 54990,
"tags": [11, 12]
}
}'
Пакетная вставка:
curl -X POST http://localhost:9308/json/bulk \
-H "Content-Type: application/x-ndjson" \
-d '
{"insert": {"index":"products", "id":7, "doc": {"title":"Фотокамера Canon EOS", "category":"photo", "price":45990}}}
{"insert": {"index":"products", "id":8, "doc": {"title":"Телевизор LG OLED", "category":"tv", "price":129990}}}
'
Создание индекса из MySQL базы данных
Конфигурация источника данных:
source products_source {
type = mysql
sql_host = localhost
sql_user = username
sql_pass = password
sql_db = ecommerce
sql_query = SELECT id, title, description, category, price, UNIX_TIMESTAMP(created_at) as created_at FROM products
sql_attr_uint = group_id
sql_attr_string = category
sql_attr_uint = price
sql_attr_timestamp = created_at
sql_field_string = title
sql_field_string = description
}
index products_main {
source = products_source
path = /var/lib/manticore/products_main
min_word_len = 3
min_infix_len = 3
expand_keywords = 1
}
Где:
- min_word_len = 3 - Определяет минимальную длину слова для индексации.
- min_infix_len = 3 - Минимальная длина префикса/инфикса для поиска (позволяет искать по первым 3+ символам).
- expand_keywords = 1 - Расширяет ключевые слова при поиске (пользователь ищет: "тест", система ищет: "тест*").
Индексация данных:
sudo -u manticore indexer --all --rotate
Далее возможно необходима перезагрузка контейнера:
docker-compose restart
Примеры поисковых запросов
Через MySQL протокол
Простой поиск:
SELECT * FROM products WHERE MATCH('смартфон');
Поиск с фильтрацией:
SELECT * FROM products
WHERE MATCH('ноутбук') AND category = 'computers' AND price < 100000;
Поиск с сортировкой:
SELECT * FROM products
WHERE MATCH('беспроводные')
ORDER BY price DESC
LIMIT 10;
Агрегационные запросы:
SELECT category, COUNT(*), AVG(price)
FROM products
GROUP BY category;
Через HTTP API
Простой поиск:
curl -X POST http://localhost:9308/search \
-H "Content-Type: application/json" \
-d '
{
"index": "products",
"query": {
"match": {
"title": "смартфон"
}
},
"limit": 10
}'
Поиск с фильтрами:
curl -X POST http://localhost:9308/search \
-H "Content-Type: application/json" \
-d '
{
"index": "products",
"query": {
"bool": {
"must": [
{"match": {"title": "ноутбук"}}
],
"filter": [
{"range": {"price": {"lte": 100000}}}
]
}
}
}'
Полезные команды для управления
Получение схемы индекса:
mysql -P 9306 -e "DESCRIBE products"
Информация о количестве документов, размере и показателях производительности:
mysql -P 9306 -e "SHOW INDEX products STATUS"
Оптимизация индекса:
mysql -P 9306 -e "OPTIMIZE INDEX products"
Получение информации об индексе:
mysql -P 9306 -e "DESC products"
mysql -P 9306 -e "SHOW META"
Базовая оптимизация
searchd {
# ... остальные настройки ...
max_children = 100
max_packet_size = 128M
workers = threads
binlog_path = /var/lib/manticore
}
index products {
# ... остальные настройки ...
morphology = stem_ru, stem_en
stopwords = /etc/manticoresearch/stopwords.txt
min_word_len = 2
}
- max_children = 100 - Ограничивает максимальное количество одновременных соединений к серверу
- max_packet_size = 128M - Увеличивает максимальный размер пакета данных
- workers = threads - Использует потоки (threads) вместо процессов (fork) для обработки запросов
- binlog_path = /var/lib/manticore - Включает бинарное логирование и указывает путь для файлов бинарного лога
- morphology = stem_ru, stem_en - Включает морфологическую обработку для русского и английского языков ("смартфоны" → "смартфон", "running" → "run")
- stopwords = /etc/manticoresearch/stopwords.txt - Загружает стоп-слова из файла (Примеры для русского: "и", "в", "на", "с", "по")
- min_word_len = 2 - Минимальная длина слова для индексации