⚠️ Эта страница автоматически переведена, и перевод может быть несовершенным.

От 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 строка запроса представляет собой полную команду SELECT SphinxQL:

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. Рассмотрим пример с статьями Wikipedia, где нам нужно получить только идентификатор статьи и заголовок (который не хранится в нашем индексе):

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

CREATE TABLE WikiSearch
(
    id INTEGER UNSIGNED NOT NULL,
    query VARCHAR(1024) NOT NULL,
    INDEX(query)
) ENGINE=FEDERATED
DEFAULT CHARSET=utf8
CONNECTION='mysql://[email protected]:9306/DB/wikipedia';
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';

Мы собираемся выполнить поиск по индексу Wikipedia в Manticore и объединить результат с таблицей Wikipedia (названной wikipediaTable) из MySQL. id и article из объединённого SELECT будут использованы для выполнения отдельного SELECT для каждой статьи, который вернёт сниппет.

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)

Для получения дополнительной информации ознакомьтесь со страницей поддержки FEDERATED в официальной документации.

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

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