Sphinx - Подключение к Sphinx из .NET
В этой статье я хочу немного отвлечься от рассказа про сам Sphinx и немного поговорить о том, как взаимодействовать с ним из программы, написанной на языке C#.
Как я уже упоминал ранее, наиболее простым и удобным способом взаимодействия со Sphinx является язык запросов SphinxQL, который сильно напоминает обычный SQL. Сами запросы можно выполнять, подключившись к Sphinx как к обычной базе данных MySQL, поскольку Sphinx умеет её эмулировать.
Тем не менее даже используя официальный коннектор MySQL для .NET, взятый с сайта mysql.com, можно столкнуться с некоторыми сложностями, о решении которых я бы и хотел поговорить в этой статье.
Приложение
Прежде всего нам потребуется Sphinx хотя бы с одним настроенным индексом. Воспользуемся индексом product, настройку которого я описывал в одной из предыдущих статей (в примере 1).
После того, как у нас будет настроенный индекс, откроем Visual Studio и создадим обычное консольное приложение. Чтобы это приложение могло взаимодействовать со Sphinx, нам необходимо подключить к нему коннектор MySQL, и тут возникает вопрос: какую версию коннектора выбрать?
Версии коннектора
Честно говоря, ещё неделю назад для я был абсолютно уверен в том, что любой коннектор версии
5.*.* должен нормально работать со Sphinx, поскольку именно эту версию (точный номер, к
сожалению, не помню) мы регулярно используем на работе. Каково же было моё удивление, когда
перепробовав все версии, доступные на сайте mysql.com я
убедился, что все они при подключении к Sphinx кидают ArgumentNullException
.
Версию 6.6.5 (самую последнюю на данный момент) использовать также не получится, т.к. разработчики внесли туда несколько изменений, из-за которых коннектор при каждом подключении к Sphinx пытается выполнить следующий запрос:
select timediff( curtime(), utc_time() )
Этот запрос, вполне корректный для MySQL, Sphinx обработать не может и возвращает ошибку.
К счастью, немного поэкспериментировав с другими версиями я обнаружил, что версии коннектора с 6.2.* по 6.5.* нормально работают, поэтому вам я рекомендую использовать одну из них.
Добавим коннектор MySQL версии 6.5.4 в наше приложение. Для этого в Visual Studio откроем Package Manager Console (Tools - Library Package Manager - Package Manager Console) и введём команду:
Install-Package MySql.Data -Version 6.5.4
Код
Теперь мы можем приступить к написанию кода. Изменим метод Main
следующим образом:
public static void Main(string[] args)
{
var connectionString = "Server=127.0.0.1;Port=9306;Character Set=utf8";
var query = "select id, name, price from product";
using (var connection = new MySqlConnection(connectionString))
using (var command = new MySqlCommand(query, connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var id = reader.GetInt32("id");
var name = reader.GetString("name");
var price = reader.GetFloat("price");
Console.WriteLine("{0}\t{1}\t{2:0.00}", id, name, price);
}
}
}
}
Как вы видите, подключение к Sphinx практически ни чем не отличаются от подключения к SQL Server. Все используемые классы имеют тот же набор методов и лишь немного отличаются названием.
Connector/Net no longer supports server versions prior to 5.0
Если мы прямо сейчас попробуем запустить наше приложение, то увидим ошибку «Connector/Net no longer supports server versions prior to 5.0». Возникает она, потому что наш коннектор подключаясь к Sphinx считает, что на самом деле подключается к базе данных MySQL, и запрашивает номер версии. Sphinx при этом возвращает версию 4, поскольку именно она задана по умолчанию. Коннектор, в свою очередь, возвращает ошибку, сообщая нам, что он не может работать с базой данных, версия которой ниже 5.
Чтобы изменить это поведение и вернуть номер версии, который бы удовлетворил используемый нами коннектор, воспользуемся опцией mysql_version_string блока searchd.
Добавим эту опцию в файл конфигурации Sphinx, указав номер версии 5.0.0:
searchd
{
...
mysql_version_string = 5.0.0
}
Перезапустим Sphinx, чтобы изменения в файле конфигурации вступили в силу. Это можно сделать либо перезапустив службу Sphinx в панели управления (Пуск - Панель управления - Администрирование - Службы), либо через командную строку, последовательно введя две команды:
net stop Sphinx
net start Sphinx
Теперь, если мы снова запустим нашу программу, то увидим на экране список товаров.
Скачать демо (Console Application, .NET 4.5)
Прошу прощения, что пишу сюда. Но не нашел, куда еще можно написать. Ты наверно заметил (хотя кто знает), что у тебя в заголовке страниц отображается адрес страницы.
ОтветитьУдалитьБольшое спасибо! Видел это, но потом забыл =)
УдалитьТам даже не адрес, там просто ничего нет. Видимо где-то в шаблоне Blogger`а я накосячил.
Вот, теперь куда лучше :)
УдалитьНу да. Многие коннекторы работают на костылях.
ОтветитьУдалитьПитоновский до определённого момента вообще падал, пытаясь распарсить VersionString.
Собственно, из-за них и навставляли "хакерские" опции, позволяющие сфинксу выдать некую точную строку, как свою версию (а на самом деле эта строка не имеет отношения к реальной версии сфинкса).
А разные вспомогательные запросы из коннектора (кто я? где я? какое сегодня число? а какая тут локаль?), в коде сфинкса закрыты загулками. Как раз-таки из-за .net-коннекторов. Но, очевидно, что заглушки не все. Нужно просто открывать багу в багтреккере, если новая версия коннектора вдруг не работает.
И желательно к такой баге прикладывать дамп полного протокола общения коннектора с демоном при подключении (там часто далеко не одна команда летит; а дамп позволит добавить их все, без итераций "пофиксили? - а нифига, новая ошибка - переоткрываем багу!")
Привет, можно ли использовать Dapper.Net для работы с Sзhinx? После стать про Joined и MultiValue немного засомневался, может быть кто-то уже использовал?
ОтветитьУдалить