Незручні моменти в роботі з Manticore як основної БД

4 хв. читання

В коментарях до матеріалу Manticore як сучасна альтернатива Sphinx мене просили зробити більш детальні інструкції роботи з цим рушієм. Утім, вважаю що інформації достатньо в документації. Натомість, хотілось би описати деякі моменти, які можуть відверто вибісити особливо тих, хто планує повний перехід з класичних баз даних типу MySQL та використання Manticore, як основної бази.

Відсутність нормалізації даних

Перше, з чим може зіткнутись користувач реляційних баз даних, який вирішив зберігати усі дані в Manticore - неможливість розбити дані по таблицям таким чином, щоб збудувати їх подальші нормалізовані зв'язки по зовнішнім ключам.

Здебільшого вся база конкретного проекту буде зберігатись в одній таблиці і варто бути готовим сприймати цю базу як по-рядкове сховище key/value. А всі дані в ній - простий масив індексів. Тому на етапі проектування, можна забути про UML, та MySQL Workbench - логіка бази даних в результаті буде повністю відрізнятись від класичної моделі зберігання SQL.

Вибірка тексту

В Manticore / SphinxQL неможливо просто зробити чітку вибірку тексту, таку як:

SELECT * FROM table WHERE field = 'value'

Якщо потрібно фільтрувати рядки по тексту, потрібно спочатку створити числовий атрибут, наприклад хеш CRC32 і фільтрувати по ньому. Інакше запит завершиться помилкою.

Вибірка підрядка

Можливо, є сторонні рушії, але стандартно ви не зможете наприклад додавати записи по умові PHP strpos та потім зробити таку само вибірку підрядка назад:

SELECT * FROM table WHERE MATCH ('@field "*alu*"')

До того ж, результат такої вибірки залежатиме від налаштувань min_word_len і min_prefix_len.

Обходити цю проблему доводиться в циклі пошукових результатів, з додатковою перевіркою strpos.

Спеціальні символи SphinxQL

Наприклад, на стадії індексації, ви заігнорили URL з символами # (якорі), ? (динамічні параметри) через умову PHP. При спробі видалити такі старі записи в індексах запитом:

DELETE FROM table WHERE MATCH ('@url "#"')

сервер видалить будь який URL, оскільки у цьому випадку # буде вважатись порожньою строкою '' :)

Операції UPDATE

Якось з'явилась ідея оптимізувати об'єм бази, перенесенням одного з полів CRC32 в індексну колонку ID. Зробити це типовою командою SQL не вдалось:

UPDATE table SET id = crc32field;

Наступною спробою, була попередня вибірка і обробка скриптом в циклі результатів, але звісно, рушій не дав того зробити, тому довелось створювати індексну таблицю повторно.

Лімітування результатів

Стандартно рушій лімітує вибірку до 1000 рядків, це не завжди зручно і потрібно додавати атрибут cutoff

Містика пагінації

Приклад вибірки на одному з проектів з використанням manticoresearch-php

echo $index->search('')->maxMatches(10000)->offset(1000)->limit(1000)->get()->getTotal();
> 5000 

Журналювання SELECT

Наприклад у вашому скрипті пошуку інтернет сторінок, використовується перевірка наявності поля по його URL, таким чином, відбуваються мільйони перевірок і всі вони потрапляють до query.log як пошукові запити користувача. Це неймовірний треш, рішення якого так і не знайшов.

Стандартна стратегія Binlog

Користувачі серверів з нестабільним підключенням до мережі живлення, можуть зіткнутись з проблемою крашу binlog, після чого сервіс Manticore просто не стартує при завантаженні системи.

Вирішується спочатку це видаленням /var/lib/manticore/binlog/* і ручним рестартом сервісу.

Коли проблема набридає, виявляється, що стандартно Manticore зберігає транзакції по-секундно, замість збереження після кожної транзакції. Можливо, щоб зробити маркетинговий ефект швидкості в роботі, але по факту доставить вам мороки в пошуках причини.

До того ж ця проблема є причиною "загадкових зникнень" деяких записів з бази (бо власне ви отримали server fault та скинули журнал відновлення binlog)

Інше

Відсутність більшості вбудованих функцій, типових для серверів SQL, можливість комбінованих запитів JOIN та інше - все це знайома ситуація, але на замітку. Будьте готові до емуляції SQL а не повної заміни.

Створення проекту на базі Manticore у якості основної бази - виправдано тільки для пошукових систем з великим об'ємом тимчасових даних, які перш за все не потребують чіткої вибірки, де MySQL є тягарем.

Можливо будуть додані рішення, якщо такі будуть знайдені. Також діліться вашим досвідом в коментарях!

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
p.s. 372
Приєднався: 1 місяць тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація