blog-post

Майк учится: ЗАМЕНИТЬ, ОБНОВИТЬ, формы слов

Обо мне

Mike

Привет, это снова Майк.

Я недавно начал работать в Manticore в качестве разработчика-адвоката. Я человек, не совсем далекий от ИТ, но я догоняю современные технологии. В этом блоге я поделюсь своим опытом и тем, что я узнаю о Manticore. Я планирую документировать свое путешествие в формате дневника, объясняя, что такое Manticore и как его использовать. Давайте узнаем, как все работает вместе, выявим проблемы и взаимодействуем с разработчиками в реальном времени.

Это мой второй блог-пост. Если вы хотите учиться о Manticore вместе со мной, я буду держать вас в курсе в:

Шаг второй: ЗАМЕНИТЬ, ОБНОВИТЬ, формы слов

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

Эта статья является продолжением предыдущей и основана на ней.

В отличие от большинства баз данных, Manticore использует продвинутую модель для распознавания текстов, которые она хранит. Система обработки текста основана на решениях NLP (обработка естественного языка).

Небольшое описание технологии для общего понимания не повредит. NLP предназначена для распознавания "естественного" языка, на котором мы общаемся. На первый взгляд, кажется, что в распознавании текста нет ничего сложного, технически это стало возможным с появлением решений для обработки текста с использованием алгоритмов машинного обучения. В нашем случае мы не будем углубляться и будем использовать готовые решения для обработки текста от Manticore Search, которые уже встроены в базу данных. Эта система использует токенизацию (разделение текста) на небольшие отдельные части: по предложениям и по отдельным словам, что позволяет быстро находить нужные слова, фразы и абзацы в целом в базе данных. (Для получения дополнительной информации о токенизации данных, ознакомьтесь с этим ссылкой. )

Вот несколько слов о технологиях, которые использует Manticore:

  • Стемминг — это процесс сокращения слов до их корневой формы. Например, "walking", "walks" и "walked" — это все формы слова "walk".
  • Лемматизация — это процесс изменения различных форм слова обратно к его базовой форме, называемой леммой. Например, слово "eat" может появляться как "eating", "eats" и "ate". Лемма для всех этих вариаций — "eat", что является его базовой словарной формой.
  • Для повышения точности и качества расширенного поиска в работе участвуют несколько других решений: формы слов, исключения и стоп-слова.

Лемматизатор и стеммер выполняют одну общую функцию нормализации слов до одной формы, но разными способами, каждый из которых имеет свои преимущества и недостатки.

Также файлы стоп-слов со списками общих слов для выбранного языка, таких как артикли, союзы и восклицания, помогают ускорить процесс. В основном, все эти маленькие слова, которые делают наш язык приятным на слух, но на самом деле не имеют большого значения для компьютера.

Если стандартного набора функций недостаточно для комфортной работы поисковой системы, например, когда база данных содержит профессиональный жаргон или местный сленг, и существуют логические связи между словами с дополнительным семантическим значением, вы можете использовать дополнительные файлы форм слов. Администратор базы данных может добавлять связи между словами в файле, которые различаются по правилам определения, но схожи по контексту с этой базой данных. Например, поводок и шлейка. В разных контекстах эти два слова могут иметь одно и то же значение или быть совершенно разными.

Использование файла форм слов в таблице

Новые таблицы

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

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

Давайте рассмотрим продукты, доступные в этом зоомагазине:

TitleDescriptionPriceAvailability
Полотняный поводок, зеленый, до 50 кг, 5мПрочный полотняный поводок для собак длиной 5 метров, подходит для крупных пород собак5.00€yes
Эластичный поводок, розовый, до 10 кг, 3мКрасивый поводок для утонченных дам и их четвероногих спутников12.00€no
Розовый шлейка, до 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 как логическое значение.

Чтобы построить логическую связь между "поводками", "шлейками" и "flexi", мы поместим их в файл в /tmp/wordforms/ и убедимся, что он доступен всем пользователям системы.

mkdir /tmp/wordforms
cd /tmp/wordforms
mcedit wf_pet_products.txt

Встроенный редактор в MC называется mcedit. Чтобы запустить его, введите mcedit <имя файла>.

Давайте добавим наши формы слов туда:

flexi > leash
harness > leash

Если вы все сделали правильно, вы увидите что-то подобное в вашем терминале:
Terminal view
F2 Сохранить
Enter Подтвердить
F10 Выйти

Теперь у нас есть файл со словами, который мы будем использовать позже с новой таблицей. Запомните или запишите, где он сохранен:

/tmp/wordforms/wf_pet_products.txt

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

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;

DESC results

Все поля, которые мы указали, присутствуют, но появилось дополнительное поле - id. Это поле предназначено для того, чтобы Manticore мог уникально идентифицировать документ в базе данных, поэтому оно автоматически создается при инициализации таблиц, независимо от спецификации. Поле info имеет свойства indexed stored, что указывает на его участие в процессе полнотекстового поиска. Важно отметить, что порядок полей отличается от последовательности, указанной при создании таблицы. Поэтому при заполнении таблицы это необходимо учитывать, особенно при обновлении целых строк без указания последовательности полей в команде. Например, в команде REPLACE, о которой мы поговорим вскоре.

Далее мы должны проверить общие параметры таблицы, такие как файл форм слов и ранее подключенный стеммер. При создании таблицы, если в имени файла форм слов есть ошибка, система проигнорирует его и не выдаст никаких ошибок или предупреждений.

SHOW TABLE products SETTINGS;

Show table products settings result

Выше вы можете заметить, что хотя мы указали путь к файлу в /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';

Result of select * from products where name...

Убедитесь, что вы запомнили, где расположены поля. Эта информация нам понадобится позже. Также нам нужны все текущие данные в полях, потому что команда 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;

Скриншот результата запроса 'where id'

Мы достигли желаемого результата, теперь давайте попробуем поиск, потому что мы создаем базу данных продуктов для магазина, чтобы продавцу было легче найти товар. Команда, используемая для поиска в таблице, это select * from <table> where match('<query>').

SELECT * FROM products WHERE match('harness');
SELECT * FROM products WHERE match ('leash');

Результат запроса для 'roulette'

Отлично, теперь база данных предоставляет ответы на наши запросы, используя соединение, которое мы создали через файл форм слов. Но, похоже, что-то не хватает в выводе? Где запись о розовом поводке для домашних охранников?
В поле info нет слов, таких как поводок или ошейник, они появляются только в поле name, поэтому эта запись не попала в вывод. Давайте это исправим:

SELECT * FROM products WHERE name = 'Pink harness, up to 10 kg';

Результат запроса "pink harness"

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');

Результат запроса 'harness' после обновления таблицы
Теперь эта запись включена в вывод. Как вы можете видеть из примера, только информация, относящаяся к индексированным полям, участвует в поиске; остальные поля являются атрибутами для индексированных полей.

Расширение таблицы

В зоомагазине привезли новые товары, теперь у них есть и аквариумное оборудование. Чтобы убедиться, что мы можем легко находить слова, связанные с аквариумными вещами, такими как насос или привод, нам нужно добавить записи в наш список слов.

НазваниеОписаниеЦенаНаличие
Насос для аквариума.Насос с встроенным фильтром для аквариума. Производительность 150 л/ч32.00€да
Автоматический фильтр для аквариумаОдноразовый привод с фильтром, производительность 100 л/ч.28.00€да
Рыбная сетьАтрауматическая рыбная сеть для аквариума3.00€да

Давайте добавим их в базу данных:

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');

Результат запроса 'pump' и 'filter'

Хорошо, это что-то значит. Однако привод не считается насосом. Это должно быть добавлено в список слов, которые мы используем…
Давайте сделаем это.
О, здесь есть небольшая проблема. Это не так просто...
Когда мы создаем систему поиска по тексту, мы помещаем все слова в таблицу и преобразуем их в токены, чтобы повысить эффективность поиска. Эти токены не обновляются впоследствии, чтобы ускорить процесс поиска. Тем не менее, бывают случаи, когда нам нужно обновить файл форм слов и, следовательно, изменить токены. Давайте обновим список слов в нашем файле форм слов и также включим название продукта в поле name в индекс поиска.

Чтобы обновить файл форм слов в таблице, я выполнил следующие шаги:

  1. Создал дамп этой таблицы с помощью mysqldump.
  2. Обновил файл форм слов.
  3. Удалил старую таблицу.
  4. Создал новую таблицу с обновленными формами слов в разделе морфологии.
  5. Заполнил новую таблицу из дамп-файла.
Создание дамп-файла (резервная копия):

В любой неясной ситуации сделайте резервную копию таблицы, чтобы предотвратить потерю данных. (Это правило можно повесить на стену как напоминание).
Это также помогает нам достичь нашей цели.
Для выполнения этой работы нам нужно отключиться от 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, и оно всегда должно быть manticore, когда вы используете mysqldump с Manticore.
  • products - это название нашей таблицы, для которой создается дамп.
  • products.sql - это имя файла, в который будет загружен дамп. Директория для размещения файла по умолчанию соответствует директории, из которой был запущен mysqldump. Я рекомендую указать /tmp/, чтобы гарантировать успешную работу примеров далее. В качестве альтернативы вы можете ввести полный путь: /tmp/manticore_dumps/products.sql.

Не беспокойтесь, если вы видите: "-- Warning: column statistics not supported by the server." Это нормально, когда вы используете этот инструмент mysql с Manticore.

Отлично, у нас есть наш первый дамп!
Дамп продукта в папке

Обновление файла форм слов:

Вы забыли, где находится исходный файл для форм слов?

cd /tmp/wordforms

Если вы используете MC и по какой-то причине не видите столбцы с файлами, попробуйте использовать комбинацию Ctrl + O. Если ничего не изменится, возможно, MC не запущен.

Расположение форм слов
Далее используйте клавиши со стрелками для навигации. Когда вам нужно выбрать файл, нажмите F4, чтобы открыть выбранный файл.
Добавьте новую строку: "drive > pump"
Файл форм слов с добавленной строкой
Сохраните и закройте. F2, Enter, F10.
Файл обновлен.

Удаление таблицы и создание новой:

Перед удалением таблицы, пожалуйста, убедитесь, что у вас есть дамп и что он определенно содержит наши данные.

cd /tmp/manticore_dumps/

Выберите дамп-файл и нажмите кнопку F3, чтобы просмотреть его.
Вы можете сделать то же самое в консоли, используя команду cat /tmp/manticore_dumps/products.sql.

Вы должны увидеть что-то вроде этого:
Dump view

Хорошо, давайте продолжим и удалим нашу старую таблицу и создадим новую:

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');

Отлично, всё работает!
Result after update wordforms "select * ... mathc('pump')"

При обновлении таблицы, особенно большой, существует период, когда старая таблица была удалена, а новая ещё не создана. В этот интервал система может отвечать на запросы с ошибками. Чтобы обеспечить бесперебойную работу на Manticore, существуют несколько систем, которые помогают избежать потери пользовательских запросов. Я научусь, как это реализовать позже.

В этой статье я показал, как я настроил и использовал Manticore Search для инвентаризации зоомагазина. Используя словообразования и морфологию, Manticore помогает улучшить результаты поиска, связывая связанные названия и типы продуктов. Я рассказал, как я добавил новые товары, обновил существующие и обеспечил согласованность данных во время крупных обновлений, таких как изменение файлов словообразований. Это помогает новичкам понять и эффективно применять функции Manticore Search, делая поиск данных более эффективным. В будущих постах мы рассмотрим больше функций, так что давайте продолжим экспериментировать с Manticore вместе, чтобы улучшить ваши проекты.

На этом всё на сегодня. Майк, прощаюсь.

end photo

Установить Manticore Search

Установить Manticore Search