Содержание
Переход от API к SphinxQL и обратно
Какой способ лучше использовать - SphinxQL или API?
Бинарный API
Бинарный API:
- самый старый способ обращения к серверу Сфинкса
- реализован на различных языках программирования, в том числе с не официальной поддержкой
Имеет недостатки:
- дополнительная нагрузка на клиент, связанная с упаковкой и распаковкой данных в двоичный формат
- клиентская библиотека для работы с API должна соответствовать версии сервера Сфинкса. Использование старой библиотеки с более новым Сфинксом может привести к неправильной интерпретации запроса и отсутствию новых возможностей поиска
- невозможно менять индексы реального времени
SphinxQL
SphinxQL - использует транспортный протокол MySQL 4.1
- не требует библиотеки API
- возможно использовать с любым клиентом MySQL
- SphinxQL - разновидность SQL, похожая на MySQL, но с отличиями
Отличия SphinxQL от MySQL
- MATCH - не то же самое, что в MySQL
- SphinxQL имеет часто используемую в запросах опцию
OPTION
, которой нет в MySQL - оператор
OR
не поддерживается в секцииWHERE
, но поддерживается в выраженияхSELECT
- возможна поддержка ORM, но требует их доработки
- есть специальная команда
SHOW META
, которая вызывается сразу послеSELECT
и показывает дополнительную информацию (общее количество найденных документов, статистику, а с версии 2.1.1 - статистику по IO и CPU (если searchd запущен с опциями--iostats
и--cpustats
)) - SphinxQL - единственный способ обновления RealTime индекса (RT), а также имеет дополнительную функциональность: очистка RT индекса, показ структуры индекса (с
DESCRIBE
).
API vs SphinxQL
Результаты запроса являются одинаковыми для обоих способов обращения. Основное отличие - некоторые запросы требуют больше определений в SphinxQL (как следствие - больше возможностей настройки).
Например, API имеет несколько режимов matching mode
, которых нет в SphinxQL. Режим в SphinxQL такой же, как SPH_MATCH_EXTENDED2
из API.
matching mode
API можно моделировать в SphinxQL:
API matching mode в SphinxQL
Режим matching mode | Запрос SphinxQL |
---|---|
SPH_MATCH_ALL | SELECT * FROM index WHERE MATCH('one two') OPTION ranker = proximity; |
SPH_MATCH_ANY | SELECT * FROM index WHERE MATCH('one | two') OPTION ranker = matchany; или SELECT * FROM index WHERE MATCH('"one two"/1') OPTION ranker = matchany; |
SPH_MATCH_PHRASE | SELECT * FROM index WHERE MATCH('"one two"') OPTION ranker = proximity; |
SPH_MATCH_BOOLEAN | SELECT * FROM index WHERE MATCH('one -two') OPTION ranker = none; |
SPH_MATCH_EXTENDED и SPH_MATCH_EXTENDED2 | SELECT * FROM index WHERE MATCH('one two'); |
SPH_MATCH_FULLSCAN | Полный перебор делается без использования конструкции MATCH |
От SphinxQL к API
Пример запроса SphinxQL:
- sphinx.sql
SELECT id,user_id FROM myindex WHERE MATCH('@title one @content two') AND property_id BETWEEN 10 and 100 ORDER BY group_id DESC,user_id ASC LIMIT 10,20 OPTION ranker=expr('sum(lcs*user_weight+exact_hit)*1000+bm25'), idf=plain, user_weight=(title=100,content=20);
На PHP через API выглядит так:
- sphinx.php
$cl = new SphinxClient(); $cl->SetMatchMode(SPH_MATCH_EXTENDED2); $cl->SetFilterRange('property_id', 10,100); $cl->SetSortMode(SPH_SORT_EXTENDED,'group_id DESC,user_id ASC'); $cl->SetFieldWeights(array('title' => 100, 'content' =>20)); $cl->SetQueryFlag('idf','plain'); $cl->SetRankingMode(SPH_RANK_EXPR,'sum(lcs*user_weight+exact_hit)*1000+bm25'); $cl->SetSelect('id,user_id'); $cl->Query('@title one @content two','myindex');
От API к SphinxQL
Типичный пример перевода геопозиции из API в SphinxQL:
- geo.php
$cl->SetGeoAnchor('latitude','longitude',1.3521,0.3432); $cl->SetSortMode(SPH_SORT_EXTENDED, '@geodist ASC'); $cl->SetFilterFloatRange('@geodist',0,1000); $cl->Query('..etc..','myindex');
SphinxQL:
Мультизапросы SphinxQL
Через API очень удобно сделать пакетный запрос из нескольких простых, который может сработать быстрее из-за механизма оптимизации мультизапросов (используется в фасетном поиске).
- multi-queries.php
$cl->SetSortMode ( SPH_SORT_RELEVANCE ); $cl->AddQuery ( "hello world", "myindex" ); $cl->SetSortMode ( SPH_SORT_ATTR_DESC, "price" ); $cl->AddQuery ( "hello world", "myindex" ); $results = $cl->RunQueries();
Результат будет содержать массив с результатами каждого запроса. Кроме того, есть методы ResetFilters()
и ResetGroupBy()
, которые делают полный сброс уже добавленных фильтров или группировки вызовов.
В SphinxQL также есть мультизапросы, которые запускаются так же, как обычные мультизапросы к MySQL.
mysqli::multi_query()
, запросы пишутся через ;
.