От SphinxSE к FEDERATED

В этой статье мы обсуждаем различия между использованием SphinxSE и FEDERATED движка с Manticore Search

Плагин MySQL SphinxSE был доступен с первого публичного релиза Sphinx Search. Идея заключалась в том, чтобы позволить пользователям выполнять поисковые запросы, используя то же соединение MySQL. Другим преимуществом было то, что результаты поиска могли быть объединены с другой таблицей MySQL для дальнейшей фильтрации/сортировки или для отображения данных, недоступных в результате поиска. Также в то время SphinxQL еще не существовал.

Одна из проблем с SphinxSE заключается в том, что плагин не включен во все версии MySQL. В настоящее время только MariaDB включает SphinxSE в свой список встроенных плагинов. Тем, кто использует MySQL или Percona, необходимо скачать исходники MySQL и скомпилировать плагин SphinxSE, что не является простым решением. Обновление MySQL до новых версий может потребовать повторной компиляции для этой версии, что усложняет процесс. Поддержка SphinxSE также была сложной с точки зрения разработки: требовалось поддерживать его в актуальном состоянии с изменениями API MySQL, а также, поскольку у него был свой собственный синтаксис поиска, поддерживать еще один парсер запросов.

Добавление поддержки FEDERATED

Недавно мы добавили в Manticore Search поддержку запросов, выполняемых на таблице FEDERATED. Поскольку FEDERATED включен по умолчанию во все версии MySQL, специальная настройка или компиляция не требуется. Все, что вам нужно сделать , это создать таблицу FEDERATED, которая ссылается на Manticore SphinxQL, и вы можете выполнять поисковые запросы.

SphinxSE требует отправлять запрос в специальном формате, как набор параметров, разделенных точкой с запятой, например

WHERE query='test;filter=cat_id,1,5,10;groupby=day:published_ts;fieldweights=title,10,abstract,3,content,1;'

Этот синтаксис никогда не охватывал все функции, например возможность делать GROUP N BY.

В FEDERATED строка запроса является полным командой SphinxQL SELECT:

WHERE query='SELECT * FROM test_index WHERE MATCH (\'test\') AND ANY(cat_id) IN (1,5,10 GROUP BY day,published_ts OPTION field_weights=(title=10,abstract=3,content=1)';

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

Ограничения

Таблица FEDERATED, подключенная к Manticore, использует схему, аналогичную таблице SphinxSE: есть обязательный столбец для строки запроса. Чтобы получить значения атрибутов из результатов поиска, они должны иметь столбцы, объявленные в таблице.

Некоторые могут спросить, почему невозможно выполнить запрос SphinxQL напрямую, вместо того чтобы помещать его в строковый столбец. Главная проблема в том, что SphinxQL имеет собственные условия, такие как MATCH(), и парсер MySQL не распознает это. Сам FEDERATED имеет некоторые недостатки, например, он игнорирует условие LIMIT.

Еще одно ограничение касается объединения с таблицей MySQL для выполнения дополнительной фильтрации или сортировки/группировки. Объединение выполняется с набором результатов, предоставленным запросом поиска Manticore. Если вам, например, нужно выполнить сортировку, включающую столбец из таблицы MySQL, который должен применяться ко всему поиску, весь набор результатов должен быть получен из Manticore. Это может быть проблемой при больших результатах. Возможно, будет лучше добавить необходимые столбцы в Manticore и выполнить желаемую операцию в Manticore.

Индекс Manticore, используемый в определении таблицы FEDERATED, должен быть индексом с хранением (обычным или RealTime).

Подсветка текста

С FEDERATED возможно выполнять извлечение фрагментов из текстов, которые хранятся только в MySQL. Настройка требует вторичной таблицы FEDERATED, которая будет использоваться для выполнения SELECT с функцией SNIPPET. Рассмотрим пример с использованием статей википедии, где мы хотим получить только идентификатор статьи и заголовок (который не хранится в нашем индексе):

Сначала мы объявляем таблицу FEDERATED, где WikiSearch будет использоваться для выполнения фактического поиска, а WikiSnippet для SELECT с извлечением фрагментов:

CODE_BLOCK_2
CODE_BLOCK_3
Мы собираемся выполнить поиск по индексу википедии из Manticore и объединить результат с таблицей википедии (названной wikipediaTable) из MySQL. id и article из объединенного выбора будут использоваться для выполнения индивидуального SELECT для каждой статьи, который вернет фрагмент.
CODE_BLOCK_4
Для получения дополнительной информации ознакомьтесь со страницей поддержки FEDERATED в официальной документации.
INDEX(query)
) ENGINE=FEDERATED
DEFAULT CHARSET=utf8
CONNECTION='mysql://[email protected]:9306/DB/wikipedia';


```sql
CREATE TABLE WikiSnippet
(
    id          INTEGER UNSIGNED NOT NULL,
    snippets    VARCHAR(1024) NOT NULL,
    query       VARCHAR(1024) NOT NULL,
    INDEX(query)
) ENGINE=FEDERATED
DEFAULT CHARSET=utf8
CONNECTION='mysql://[email protected]:9306/DB/wikipedia';

We're going to perform a search on the wikipedia index from Manticore and join the result with the wikipedia table (named wikipediaTable) from MySQL. The id and article from the joined select will be used to perform an individual SELECT for each article that will return back the snippet.

mysql> SELECT id,
(SELECT snippets FROM WikiSnippet WHERE query=concat('SELECT SNIPPET(\'',a.title,'\',\'town\') AS snippets FROM wikipedia WHERE id=',a.id)) AS snippet
 FROM ( SELECT WikiSearch.id,wikipediaTable.title FROM WikiSearch JOIN wikipediaTable ON WikiSearch.id=content.id WHERE
         query='SELECT id FROM wikipedia WHERE match(\'@title town\')') a;
+-----------+----------------------------------------------------------+
| id        | snippet                                                  |
+-----------+----------------------------------------------------------+
| 221741590 | New England <b>town</b>                                  |
| 225879601 | <b>Town</b> meeting                                      |
| 227372942 | Huddersfield <b>Town</b> F.C.                            |
| 227789260 | Cape <b>Town</b>                                         |
| 228005065 | Lincoln <b>Town</b> Car                                  |
| 228031371 | Swindon <b>Town</b> F.C.                                 |
| 228037958 | Newburgh (<b>town</b>), New York                         |
| 209273335 | Lewiston (<b>town</b>), New York                         |
| 218353936 | List of Cape <b>Town</b> suburbs                         |
| 218900544 | New <b>Town</b>, Prague                                  |
| 219113587 | History of Swindon <b>Town</b> F.C.                      |
| 221331452 | Chrysler <b>Town</b> and Country                         |
| 222331137 | List of Ipswich <b>Town</b> F.C. statistics and records  |
| 225807671 | East Hampton (<b>town</b>), New York                     |
| 226345846 | Old <b>Town</b>                                          |
| 226474919 | Sengkang New <b>Town</b>                                 |
| 227031418 | Camden <b>Town</b>                                       |
| 227043533 | List of <b>town</b> tramway systems in the United States |
| 227328024 | Ghost <b>town</b>                                        |
| 227337559 | <b>Town</b>                                              |
+-----------+----------------------------------------------------------+
20 rows in set (0.01 sec)

For more information, check out the FEDERATED support page in the official documentation.

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

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