О себе

Привет, это снова Майк.
Я недавно начал работать в Manticore в роли Developer Advocate. Я не полностью оторван от ИТ, но догоняю современные технологии. В этом блоге я буду делиться своим опытом и тем, что узнаю о Manticore. Я планирую документировать своё путешествие в формате дневника, объясняя, что такое Manticore и как его использовать. Давайте узнаем, как всё работает вместе, выявим проблемы и будем взаимодействовать с разработчиками в реальном времени.
Это мой второй пост в блоге. Если вам интересно изучать Manticore вместе со мной, я буду держать вас в курсе в:
Шаг второй: REPLACE, UPDATE, wordforms
Пока я писал свою первая статья , мои друзья из зоомагазина обратились ко мне. Они хотят использовать базу данных для своего магазина, и поскольку их продавец всё ещё путает поводки и ошейники, я хочу внедрить дополнительные функции базы данных.
Эта статья служит продолжением предыдущей и основана на ней.
В отличие от большинства баз данных, Manticore использует продвинутую модель для распознавания хранимых текстов. Система обработки текста основана на решениях NLP (Natural Language Processing).
Небольшое описание технологии для общего понимания здесь не помешает. NLP предназначен для распознавания «естественного» языка, на котором мы общаемся. На первый взгляд кажется, что в распознавании текста нет ничего сложного, но технически это стало так с появлением решений по обработке текста, использующих алгоритмы машинного обучения. В нашем случае мы не будем уходить в глубину и воспользуемся готовыми решениями по обработке текста от Manticore Search, которые уже встроены в базу данных. Эта система использует токенизацию (разделение текста) на небольшие отдельные части: по предложениям и по отдельным словам, что позволяет быстро находить нужные слова, фразы и абзацы в целом в базе данных. (Для получения дополнительной информации о токенизации данных, посмотрите эту link. )
Вот несколько слов о технологиях, которые использует Manticore:
- Стемминг — процесс приведения слов к их корневой форме. Например, «walking», «walks» и «walked» являются стеммами слова «walk».
- Лемматизация — процесс преобразования различных форм слова к его базовой форме, называемой леммой. Например, слово «eat» может появляться как «eating», «eats» и «ate». Лемма для всех этих вариантов — «eat», что является его базовой словарной формой.
- Для повышения точности и качества расширенного поиска в работе задействованы несколько других решений: словоформы, исключения и стоп-слова.
Лемматизатор и стеммер выполняют одну общую функцию нормализации слов до одинаковой формы, но разными способами, каждый из которых имеет свои преимущества и недостатки.
Также файлы стоп-слов со списками часто используемых слов для выбранного языка, таких как артикли, союзы и восклицания, помогают ускорить процесс. По сути, это все маленькие слова, которые делают наш язык красивым, но не имеют большого значения для компьютера.
Если стандартный набор функций недостаточен для комфортной работы поисковой системы, например, когда в базе данных присутствует профессиональный жаргон или местный сленг, и существуют логические связи между словами с дополнительным семантическим значением, можно использовать дополнительные файлы словоформ. Администратор базы данных может добавить ссылки между словами в файле, которые различаются по правилам определения, но схожи по контексту для этой базы данных. Например, поводок и ошейники. В разных контекстах эти два слова могут иметь одинаковое значение или быть совершенно разными.
Использование файла словоформ в таблице
Новые таблицы
Парни из зоомагазина упомянули, что их продавец не очень осведомлён о поводках и ошейниках. Они советуют, что при запросе о поводке следует также учитывать запросы об ошейниках, и наоборот.
Поскольку поводки и ошейники относятся к одной категории продуктов и в базе данных нет отдельного поля для указания их группы, использование файла словоформ может быть полезным. Этот файл может помочь, позволяя добавлять связанные слова при поиске «leash». Например, добавив слова «harness» или «flexi» в словарь словоформ, поиск по «leash» также вернёт результаты для «harness» и «flexi».
Давайте рассмотрим товары, доступные в этом зоомагазине:
| Название | Описание | Цена | Наличие |
|---|---|---|---|
| Канатный поводок, зеленый, до 50 кг, 5м | Прочный канатный поводок длиной 5 метров, подходящий для крупных пород собак | 5.00€ | да |
| Эластичный поводок, розовый, до 10 кг, 3м | Красивый поводок для изысканных дам и их четвероногих спутников | 12.00€ | нет |
| Розовый шлейка, до 10 кг | Для охранников помещений, выпущенных на улицу и ошибочно названных собаками | 8.00€ | да |
| Flexi-удлиняемый поводок, 10 кг, 5м | Flexi для собак до 10 кг. Длина составляет 5 метров, учитывая длину вытянутой руки владельца | 7.50€ | да |
| Собачий корм, 1кг | Сухой корм для вашего питомца | 4.30€ | нет |
| Кошачий корм, 1кг | Если ваш кот громко мяукает и требует еду! | 2.80€ | да |
| Противоблоха ошейник для кошек | Кошки не должны быть переносчиками блох. | 23.20€ | да |
| Капли от блох для собак до 10 кг | Капли от нежелательных пассажиров на коже вашего защитника | 14.30€ | да |
Мы сделаем поле Title просто строкой, будем использовать Description для полнотекстового поиска, зададим Price как число с плавающей точкой, а Availability как логическое значение.
Чтобы построить логическую связь слов между «leashes», «harness» и «flexi», мы разместим их в файле в /tmp/wordforms/ и убедимся, что он доступен всем пользователям системы.
mkdir /tmp/wordforms
cd /tmp/wordforms
mcedit wf_pet_products.txt
Встроенный редактор в MC называется mcedit. Чтобы запустить его, введите mcedit <file name>.
Давайте добавим наши wordforms туда:
flexi > leash
harness > leash
Если всё сделано правильно, вы увидите что-то подобное в вашем терминале:
F2 Сохранить
Enter Подтвердить
F10 Выход
Теперь у нас есть файл со словами, который мы будем использовать позже с новой таблицей. Запомните или запишите, где он сохранён:
/tmp/wordforms/wf_pet_products.txt
Теперь, чтобы внести дополнительные изменения в базу данных, нам нужно подключиться к ней и создать таблицу с нашими столбцами. Затем нам необходимо связать стеммер и файл wordforms, который мы создали ранее:
mysql -h0 -P9306
CREATE TABLE products (name STRING, info TEXT, price FLOAT, avl BOOL) morphology = 'stem_en' wordforms='/tmp/wordforms/wf_pet_products.txt';
Теперь проверим, какие поля были созданы в нашей таблице:
DESC products;

Все указанные нами поля присутствуют, но появилось дополнительное поле — id. Это поле предназначено для того, чтобы Manticore мог уникально идентифицировать документ в базе данных, поэтому оно автоматически создаётся при инициализации таблиц, независимо от спецификации. Поле info имеет свойства indexed stored, указывающие на его участие в процессе полнотекстового поиска. Важно отметить, что порядок полей отличается от последовательности, указанной при создании таблицы. Поэтому при заполнении таблицы это необходимо учитывать, особенно при обновлении целых строк без указания последовательности полей в команде. Например, в команде REPLACE, о которой мы поговорим позже.
Далее нам следует проверить общие параметры таблицы, такие как файл словоформ и ранее подключённый стеммер. При создании таблицы, если в названии файла wordforms допущена ошибка, система просто игнорирует её и не выдаёт никаких ошибок или предупреждений.
SHOW TABLE products SETTINGS;

Выше вы можете заметить, что хотя мы указали путь к файлу в /tmp/wordforms/, Manticore сохранил его в /var/lib/manticore/products/. Это означает, что Manticore прикрепил копию файла к созданной таблице. Файл теперь фиксирован для индексации этой таблицы. Замена файла словоформ «на лету» недоступна по задумке, так как потребует переиндексации всей таблицы, что может быть нежелательно при очень большой таблице. Мы обсудим, как безопасно и предсказуемо заменить такой файл позже.
Это завершает настройку таблицы, а следующий шаг — ввод требуемых данных. Ввод данных осуществляется так же, как в любой базе данных SQL.
INSERT INTO products (name, price, avl) VALUES ('Canvas leash, green, up to 50 kg, 5m', 5.0, 1);
INSERT INTO products (name, price, avl, info) VALUES ('Elastic leash, pink, up to 10 kg, 3m', 12.00, 0, 'A beautiful leash for sophisticated ladies and their four-legged companions');
INSERT INTO products (name, price, avl, info) VALUES ('Pink harness, up to 10 kg', 8.00, 1, 'For room guards released into the street and mistakenly called a dog');
INSERT INTO products (name, price, avl, info) VALUES ('The flexi retractable dog leash, 10 kg, 5m', 7.50, 1, 'A flexi for dogs up to 10 kg. The length is 5 meters, taking into account the length of the owner\'s pulled out arm');
INSERT INTO products (name, price, avl, info) VALUES ('Dog food, 1kg', 4.30, 0, 'Dry food for your pet');
INSERT INTO products (name, price, avl, info) VALUES ('Cat food, 1kg', 2.80, 1, 'If your cat is yelling loudly and demanding food!');
INSERT INTO products (name, price, avl, info) VALUES ('Flea collar for cats , 1kg', 23.20, 1, 'Cats shouldn\'t be flea carriers.');
INSERT INTO products (name, price, avl, info) VALUES ('Flea drops for dogs up to 10 kg', 14.30, 1, 'Drops from uninvited passengers on the skin of your defender');
Будьте осторожны с апострофами; в тексте есть сокращения, использующие их, и важно изолировать их от остального текста с помощью \: 'Isn\'t it'. Manticore не поддерживает двойные кавычки для строк, что было бы полезно, чтобы избежать экранирования одинарных апострофов.
В первом запросе выше поле info было намеренно опущено, чтобы продемонстрировать, как обновлять полнотекстовое поле. Важно отметить, что обновление текстовых полей и полей‑атрибутов обрабатывается по‑разному. Поля полнотекстового поиска обновляются командой REPLACE, которая инициирует переиндексацию новых значений, тогда как команда UPDATE достаточна для остальных полей. Это связано с тем, что поля‑атрибуты не участвуют в процессе индексации полнотекстового поиска.
Теперь используем команду REPLACE, чтобы добавить данные в определённые поля существующих записей. Для использования этой команды вам понадобится уникальный ID строки, в которой мы хотим внести изменения или добавить информацию. Сначала получим необходимые данные, выполнив SELECT * FROM products;
SELECT * FROM products WHERE name = 'Canvas leash, green, up to 50 kg, 5m';

Убедитесь, что запомнили, где находятся поля. Эта информация понадобится позже. Кроме того, нам нужны все текущие данные в полях, потому что команда replace обновит весь файл этими данными. Если мы не укажем все данные, неуказанные поля будут сброшены. Заполните команду REPLACE в соответствии с расположением полей.
REPLACE INTO products VALUES (<id>, <info>, <avl>, <price>, <name>);
В версии разработки, которая может уже быть выпущена к моменту вашего чтения, возможно заменять отдельные поля. Для получения более подробной информации обратитесь к документации .
REPLACE INTO products VALUES (8217224102746783745, 'Sturdy canvas dog leash for 5 meters, suitable for large dog breeds', 1, 5.0, 'Canvas leash, green, up to 50 kg, 5m');
Будьте осторожны с кодом здесь: если вы просто скопируете команды из статьи, значение поля ID в вашей таблице будет другим! Если Manticore не найдёт запись с указанным ID, будет создана новая запись.
Чтобы обновить поля «attributes», вы можете использовать команду UPDATE. Кстати, при вводе данных цена слегка упала на зелёном поводке:
update products set price = 4.6 where id = 8217224102746783745;
Проверим результат:
SELECT * FROM products WHERE id = 8217224102746783745;

Мы достигли желаемого результата, теперь давайте попробуем поиск, потому что мы создаём базу данных товаров для магазина, чтобы продавцу было проще находить продукт. Команда для поиска в таблице выглядит так: select * from <table> where match('<query>').
SELECT * FROM products WHERE match('harness');
SELECT * FROM products WHERE match ('leash');

Отлично, теперь база данных предоставляет ответы на наши запросы, используя соединение, которое мы создали через файл word form. Но кажется, в выводе чего‑то не хватает? Где запись о розовом поводке для внутренних охранников?
В поле info нет слов вроде leash или collar, они присутствуют только в поле name, поэтому эта запись не попала в вывод. Давайте исправим это:
SELECT * FROM products WHERE name = 'Pink harness, up to 10 kg';

REPLACE INTO products VALUES (8217224102746783747,'Harness for room guards released into the street and mistakenly called a dog', 1, 8.0, 'Pink harness, up to 10 kg');
Проверим, что произошло:
SELECT * FROM products WHERE match('harness');

Теперь эта запись включена в вывод. Как видно из примера, в поиск участвует только информация, относящаяся к индексируемым полям; остальные поля являются атрибутами для индексируемых полей.
Расширение таблицы
В зоомагазине привезли новые товары, теперь у них есть и оборудование для аквариумов. Чтобы мы могли легко находить слова, связанные с аквариумным оборудованием, такие как pump или drive, необходимо добавить соответствующие записи в наш список слов.
| Название | Описание | Цена | Наличие |
|---|---|---|---|
| The pump for the aquarium. | A pump with a built-in filter for the aquarium. Capacity 150 l/h | 32.00€ | yes |
| Automatic filter for aquarium | Disposable drive with filter, capacity 100 l/h. | 28.00€ | yes |
| Fish net | Atraumatic aquarium fish net | 3.00€ | yes |
Добавим их в базу данных:
INSERT INTO products (name, info, price, avl) VALUES ('The pump for the aquarium.', 'Pump with built-in aquarium filter. Capacity 150 l/h', 32, 1), ('Automatic filter for aquarium', 'Disposable drive with filter, capacity 100 l/h', 28.00, 1), ('Fish net', 'Atraumatic aquarium fish net', 3, 1);
Здесь мы заполнили таблицу одной командой с перечислением новых строк через запятую, поэтому вы можете добавить большую партию документов одной командой.
Проверим поиск:
SELECT * FROM products WHERE match ('pump');
SELECT * FROM products WHERE match ('filter');

Хорошо, это что‑то значит. Однако привод не считается насосом. Это следует добавить в список используемых слов…
Сделаем это.
Ой, здесь небольшая проблема. Это не так просто…
Когда мы создаём систему поиска текста, мы помещаем все слова в таблицу и преобразуем их в токены, чтобы повысить эффективность поиска. Эти токены затем не обновляются, чтобы ускорить процесс поиска. Тем не менее, бывают случаи, когда необходимо обновить файл wordforms и, соответственно, изменить токены. Давайте обновим список слов в нашем файле wordforms и также включим название продукта из поля name в поисковый индекс.
Чтобы обновить файл wordforms в таблице, я выполнил следующие шаги:
- Создать дамп этой таблицы с помощью
mysqldump. - Обновить файл wordforms.
- Удалить старую таблицу.
- Создать новую таблицу с обновлёнными словоформами в разделе морфологии.
- Заполнить новую таблицу из дампа.
Создание дампа файла (резервная копия):
В любой неясной ситуации сделайте резервную копию таблицы, чтобы избежать потери данных. (Это правило можно разместить на стене в качестве напоминания).
Это также помогает нам достичь цели.
Для выполнения этой задачи нам нужно отключиться от SQL‑соединения и использовать инструмент mysqldump.
exit;
mkdir /tmp/manticore_dumps
cd /tmp/manticore_dumps
mysqldump -h0 -P9306 -tc --compact manticore products > products.sql
Использованные мной флаги:
-t— исключить операторcreate tableиз дампа.-c— указать имена столбцов в командахINSERT.--compact— выполнить дамп базы данных в компактном формате, который опускает процедуры проверки доступности таблиц, их удаление, создание новых, настройку конфигураций созданных таблиц и другие организационные действия при развертывании. В нашем случае эти процедуры не требовались, так как нам нужно было зарегистрировать новый файл словаря в таблице.manticore— имя базы данных дляmysqldump; при использованииmysqldumpс Manticore оно всегда должно бытьmanticore.products— имя нашей таблицы, для которой создаётся дамп.products.sql— имя файла, в который будет загружен дамп. Папка для размещения файла по умолчанию совпадает с каталогом, из которого был запущенmysqldump. Я рекомендую указывать/tmp/, чтобы примеры дальше работали успешно. При желании можно указать полный путь:/tmp/manticore_dumps/products.sql.
Не беспокойтесь, если видите: "-- Warning: column statistics not supported by the server." Это нормально при использовании этого инструмента mysql с Manticore.
Отлично, у нас первый дамп!
Обновление файла wordforms:
Вы забыли, где находится исходный файл для словоформ?
cd /tmp/wordforms
Если вы используете MC и по какой‑то причине не видите столбцы с файлами, попробуйте комбинацию Ctrl + O. Если ничего не меняется, возможно, MC не запущен.

Далее используйте клавиши со стрелками для навигации. Когда нужно выбрать файл, нажмите F4, чтобы открыть выбранный файл.
Добавьте новую строку: "drive > pump"
Сохранить и закрыть. F2, Enter, F10.
Файл обновлён.
Удаление таблицы и создание новой:
Прежде чем удалять таблицу, убедитесь, что у вас есть дамп и что он действительно содержит наши данные.
cd /tmp/manticore_dumps/
Выберите файл дампа и нажмите кнопку F3, чтобы просмотреть его.
То же самое можно сделать в консоли, используя команду cat /tmp/manticore_dumps/products.sql.
Вы должны увидеть что-то подобное:
Хорошо, давайте удалим старую таблицу и создадим новую:
mysql -h0 -P9306
DROP TABLE products;
CREATE TABLE products (name TEXT, info TEXT, price FLOAT, avl BOOL) morphology = 'stem_en' wordforms='/tmp/wordforms/wf_pet_products.txt';
Итак, мы удалили эту таблицу, а затем сразу же создали её заново (используя ту же команду, что и раньше, но с небольшим изменением: теперь поле name также предназначено для текста), и теперь нам нужно добавить в неё информацию.
exit;
Восстановление из дампа:
mysql -h0 -P9306 < /tmp/manticore_dumps/products.sql
mysql -h0 -P9306
Мы заполнили её. Давайте проверим, что у нас в итоге:
SELECT * FROM products WHERE match ('pump');
Отлично, всё работает!
При обновлении таблицы, особенно большой, существует период, когда старая таблица уже удалена, а новая ещё не создана. В этот промежуток система может отвечать на запросы ошибками. Чтобы обеспечить бесперебойную работу Manticore, существуют несколько механизмов, помогающих избежать потери пользовательских запросов. Я изучу, как их реализовать, позже.
В этой статье я показал, как настроил и использовал Manticore Search для инвентаря зоомагазина. С помощью wordforms и морфологии Manticore улучшает результаты поиска, связывая связанные названия и типы продуктов. Я описал, как добавлял новые элементы, обновлял существующие и обеспечивал согласованность данных при крупных обновлениях, таких как изменение файлов wordforms. Это помогает новичкам понять и эффективно применять возможности Manticore Search, делая поиск данных более эффективным. В будущих публикациях будут рассмотрены дополнительные функции, так что давайте продолжать экспериментировать с Manticore вместе, чтобы улучшать ваши проекты.
На сегодня всё. Майк, заканчиваю.

