blog-post

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

Обо мне

Mike

Здравствуйте, это снова Майк.

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

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

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

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

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

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

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

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

  • Стемминг — это процесс сведения слов к их корневой форме. Например, “гуляя”, “гуляет” и “гулял” — это все стеммы слова “гулять”.
  • Лемматизация — это процесс преобразования различных форм слова обратно в его базовую форму, называемую леммой. Например, слово “есть” может появляться как “едя”, “ест” и “ел”. Лемма для всех этих вариантов — “есть”, что является ее основной словарной формой.
  • Для повышения точности и качества продвинутого поиска в работе участвуют несколько других решений: формы слов, исключения и стоп-слова.

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

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

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

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

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

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

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

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

TitleDescriptionPriceAvailability
Полотняный поводок, зеленый, до 50 кг, 5мПрочный полотняный поводок для собак длиной 5 метров, подходит для крупных пород собак5.00€yes
Эластичный поводок, розовый, до 10 кг, 3мКрасивый поводок для изысканных дам и их четвероногих компаньонов12.00€no
Розовый хомут, до 10 кгДля охранников в помещениях, выпущенных на улицу и ошибочно названных собакой 8.00€yes
Удлинитель для собак Flexi, 10 кг, 5мFlexi для собак до 10 кг. Длина 5 метров, учитывая длину вытянутой руки владельца7.50€yes
Корм для собак, 1кгСухой корм для вашего питомца4.30€no
Корм для кошек, 1кгЕсли ваша кошка громко кричит и требует еды! 2.80€yes
Блохогон для кошекКошки не должны быть носителями блох.23.20€yes
Капли от блох для собак до 10 кгКапли от нежеланных пассажиров на коже вашего защитника14.30€yes

Мы сделаем поле Title просто строкой, используем Description для полнотекстового поиска, установим Price как число с плавающей запятой и Availability как логическое значение.

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

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

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

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

flexi > поводок
хомут > поводок

Если вы все сделали правильно, вы увидите что-то похожее на это в вашем терминале:
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 ('Полотно для поводков, зеленый, до 50 кг, 5м', 5.0, 1);
INSERT INTO products (name, price, avl, info) VALUES ('Эластичный поводок, розовый, до 10 кг, 3м', 12.00, 0, 'Красивый поводок для утонченных дам и их четвероногих спутников');
INSERT INTO products (name, price, avl, info) VALUES ('Розовый хомут, до 10 кг', 8.00, 1, 'Для охранников в помещениях, выпущенных на улицу и ошибочно названных собакой');
INSERT INTO products (name, price, avl, info) VALUES ('Удлинитель для собак Flexi, 10 кг, 5м', 7.50, 1, 'Flexi для собак до 10 кг. Длина 5 метров, учитывая длину вытянутой руки владельца');
INSERT INTO products (name, price, avl, info) VALUES ('Корм для собак, 1кг', 4.30, 0, 'Сухой корм для вашего питомца');
INSERT INTO products (name, price, avl, info) VALUES ('Корм для кошек, 1кг', 2.80, 1, 'Если ваша кошка громко кричит и требует еды!');
INSERT INTO products (name, price, avl, info) VALUES ('Блохогон для кошек , 1кг', 23.20, 1, 'Кошки не должны быть носителями блох.');
INSERT INTO products (name, price, avl, info) VALUES ('Капли от блох для собак до 10 кг', 14.30, 1, 'Капли от нежеланных пассажиров на коже вашего защитника');

Будьте осторожны с апострофами; в тексте есть сокращения, использующие их, и важно изолировать их от остального текста с помощью \: 'Разве это не так?'. Manticore не поддерживает двойные кавычки для строк, что было бы полезно для избежания экранирования одиночных апострофов.

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

Теперь давайте используем команду REPLACE, чтобы добавить данные в определенные поля существующих записей. Чтобы использовать эту команду, вам понадобится уникальный идентификатор строки, в которой мы хотим внести изменения или добавить информацию. Сначала мы получим необходимые данные с помощью SELECT * FROM products;

SELECT * FROM products WHERE name = 'Canvas leash, green, up to 50 kg, 5m';

Результат select * from products where name&hellip;

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

REPLACE INTO products VALUES (<id>, <info>, <avl>, <price>, <name>);

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

REPLACE INTO products VALUES (8217224102746783745, 'Стойкий холщовый поводок для собак на 5 метров, пригодный для крупных пород собак', 1, 5.0, 'Canvas leash, green, up to 50 kg, 5m');

Будьте осторожны с кодом здесь, если вы просто скопируете команды из статьи, значение поля ID в вашей таблице будет другим! Если Manticore не найдет запись с указанным ID, будет создана новая запись.

Чтобы обновить поля “атрибуты”, вы можете использовать команду UPDATE. Просто как примечание, во время ввода данных цена слегка упала на зеленом поводке:

update products set price = 4.6 where id = 8217224102746783745;

Давайте проверим результат:

SELECT * FROM products WHERE id = 8217224102746783745;

Скриншот результата запроса &lsquo;where id&rsquo;

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

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

Результат запроса для &lsquo;roulette&rsquo;

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

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

Результат запроса из &ldquo;pink harness&rdquo;

REPLACE INTO products VALUES (8217224102746783747,'Шлейка для комнатных охранников, выпущенных на улицу и ошибочно названных собакой', 1, 8.0, 'Pink harness, up to 10 kg');

Давайте проверим, что произошло:

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

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

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

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

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

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

INSERT INTO products (name, info, price, avl) VALUES ('Помпа для аквариума.', 'Помпа с встроенным фильтром для аквариума. Производительность 150 л/ч', 32, 1), ('Автоматический фильтр для аквариума', 'Утилизируемый привод с фильтром, производительность 100 л/ч', 28.00, 1), ('Рыболовная сеть', 'Атравматичная рыбная сеть для аквариума', 3, 1);

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

Давайте проверим поиск:

SELECT * FROM products WHERE match ('pump');
SELECT * FROM products WHERE match ('filter');

Результат запроса &lsquo;pump&rsquo; и &lsquo;filter&rsquo;

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

Вы должны увидеть что-то вроде этого:
Просмотр дампа

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

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

Отлично, всё работает!
Результат после обновления словоформ &ldquo;select * &hellip; mathc(&lsquo;pump&rsquo;)&rdquo;

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

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

На этом всё на сегодня. Майк завершает.

конечное фото

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

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