Sphinx для поиска по MySQL базе данных. Обработка результатов на PHP

Веб программирование Sphinx для поиска по MySQL базе данных. Обработка результатов на PHP

Помечено: , ,

  • В этой теме 0 ответов, 1 участник, последнее обновление 1 год, 7 месяцев назад сделано Васильев Владимир Сергеевич.
Просмотр 0 веток ответов
  • Автор
    Сообщения
    • #5302
      @admin

      Установка Sphinx Linux Debian

      Как ставить

      # Устанавливаем зависимости, нужные сфинксу
      sudo apt-get install mysql-client unixodbc libpq5
      

      Скачиваем последний релиз (.deb) версию Sphinx Release И ставим её

      sudo dpkg -i sphinxsearch_2.1.9-release-1_amd64.deb
      

      Выводит что-то и строку sphinxsearch is started что нам и нужно.

      Для проверки версии sphinx:

      # searchd
      Sphinx 2.0.4-release (r3135)
      Copyright (c) 2001-2012, Andrew Aksyonoff
      Copyright (c) 2008-2012, Sphinx Technologies Inc (http://sphinxsearch.com)
      
      FATAL: no readable config file (looked in /etc/sphinxsearch/sphinx.conf, ./sphinx.conf)
      

      если при searchd появляется ошибка FATAL: failed to lock pid file ‘/var/run/sphinxsearch/searchd.pid’: Resource temporarily unavailable (searchd already running?) Можно просто сделать так

      #смотрим в файл
      vim /var/run/sphinxsearch/searchd.pid
      # в файле одна циферка - № процесса (11648)
      kill 11648
      

      все, searchd работает

      Настройка Sphinx

      Удивительная особенность: создавать индексы, указывая не основной конфиг можно, а искать по таким индексам не получится, ищет только по конфигу : /etc/sphinxsearch/sphinx.conf

      Конфиг лежит по пути /etc/sphinxsearch/ берем его за основу, и делаем свой, для начала маленький:

      source s_DB
      {
      	# настройки подключения к БД
      	type			= mysql
      	sql_host		= localhost
      	sql_user		= userName
      	sql_pass		= SecPhrase
      	sql_db			= test
      	sql_port		= 3306	# optional, default is 3306
      	#ru
      	sql_query_pre		= SET NAMES utf8
      	sql_query_pre 		= SET CHARACTER SET utf8
      	#так быстрее, чем через tcp ip
      	sql_sock		= /var/run/mysqld/mysqld.sock
      
      	mysql_connect_flags	= 32 # 32- включение сжатие при обмене данными с БД
      }
      
      source item : s_DB
      {
      	sql_query		= \
      		SELECT id, title \
      		FROM items
      
          sql_attr_string = title
      }
      
      index item
      {
      	source			= item
      	path			= /home/user/project/var/sphinx/data/index/item
      	charset_type		= utf-8
      }
      
      indexer
      {
      	mem_limit		= 32M
      }
      
      searchd
      {
      	listen			= 9312
      	listen			= 9306:mysql41
      	log			= /var/log/sphinxsearch/searchd.log
      	query_log		= /var/log/sphinxsearch/query.log
      	read_timeout		= 5
      	client_timeout		= 300
      	max_children		= 30
      	pid_file		= /var/run/sphinxsearch/searchd.pid
      	max_matches		= 1000
      	seamless_rotate		= 1
      	preopen_indexes		= 1
      	unlink_old		= 1
      	mva_updates_pool	= 1M
      	max_packet_size		= 8M
      	max_filters		= 256
      	max_filter_values	= 4096
      	max_batch_queries	= 32
      	workers			= threads # for RT to work
      	compat_sphinxql_magics	= 1
      }
      

      Запускаем индексацию:

      $sudo -u sphinxsearch indexer item --config /etc/sphinxsearch/sphinx.conf --rotate --print-queries
      

      Перезапускаем sphinx: Пришлось сделать владельцем sphinxsearch /var/log/sphinxsearch И /var/run/sphinxsearch иначе выдавало какие-то warnings

      $/etc/init.d/sphinxsearch restart
      

      Ищем в индексах:

      $search --config /etc/sphinxsearch/sphinx.conf comp
      

      Доступно о сфинксе на русском написано у Игоря Чакрыгина: http://chakrygin.ru/2013/03/sphinx-install.html

      Поиск из пхп

      Рассмотрим на примере

      $page = 0; //передаем в скрипт текущую страницу
      $in_page = 12; // сколько выводить на странице
      // фраза для поиска по базе 
      $phrase = 'phrase'; 
      // подключаем Сфинкс 
      $sphinx = new SphinxClient; 
      $sphinx->SetServer("localhost", 9312); 
      // режим поиска 
      $sphinx->SetMatchMode( SPH_MATCH_EXTENDED ); // ищем хотя бы 1 слово из поисковой фразы 
      // устанавливаем вес полей (коэффициент/индекс релевантности) 
      $sphinx->SetFieldWeights(array ( 
          'title' => 50, 
          'short_title' => 40, 
          'mini_title' => 30, 
          'condition' => 10, 
          'info' => 10, 
          'description' => 15, 
          'price_description' => 5, 
      )); 
      // упорядочивание результатов по атрибутам 
      switch($this->request->post('sort')){ 
          case 'price': 
              $sphinx->setSortMode(SPH_SORT_ATTR_ASC, 'min_item_price'); 
              break; 
          case 'price_desc': 
              $sphinx->setSortMode(SPH_SORT_ATTR_DESC, 'max_item_price'); 
              break; 
          case 'new': 
              $sphinx->setSortMode(SPH_SORT_ATTR_DESC, 'sale_start'); 
              break; 
          default: $sphinx->setSortMode(SPH_SORT_ATTR_DESC, 'buy_count'); 
      }
      //устанавливаем всякие фильтры 
      $sphinx->setFilter('bonus', array(1)); 
      // находим диапазон цен, по фильтрам 
      $sphinx->SetSelect('1 AS group_attr, MAX(max_item_price) AS max_price, MIN(min_item_price) AS min_price'); 
      $sphinx->setGroupBy('group_attr', SPH_GROUPBY_ATTR); 
      $sphinx->AddQuery($phrase); 
      $sphinx->resetGroupBy(); 
      $sphinx->SetSelect('*'); 
      //фильтр по диапазону цен 
      $price_from = intval($this->request->post('price_from')); 
      $price_to = $this->request->post('price_to'); 
      if(isset($price_to)){ 
          $price_to = intval($price_to); 
          $sphinx->setFilterRange('price', $price_from, $price_to); 
      } 
      $sphinx->SetLimits($page*$in_page, $in_page, 1000); 
      $sphinx->AddQuery($phrase); 
      $result = $sphinx->runQueries(); // поисковый запрос 
      if ( $result === false ) { 
          echo 'Sphinx ошибка поиска :error', array(':error'=>$sphinx->GetLastError());
      } else { 
          if ( $sphinx->GetLastWarning() ) { 
              Log::instance()->add(Log::WARNING, 'Sphinx warning :warning', array(':warning'=>$sphinx->GetLastWarning()));
          } 
          if ( ! empty($result[1]["matches"]) ) { 
              // если есть результаты поиска - обрабатываем их
       } } 

      Библиотека для PHP

      Если на экране Class ‘SphinxClient’ not found то нужно сделать следующее:

      $sudo apt-get install php-pear
      $sudo apt-get install php5-dev
       

      Качаем отсюда же https://sphinxsearch.com/downloads/ Source tarball (tar.gz)

      $tar -xcf sphinx-2.1.9-release.tar.gz
      $cd sphinx-2.1.9-release/api/libsphinxclient
      $./configure
      $make
      $sudo make install
      $sudo sudo pecl install sphinx
       

      Дальше от версии PHP на сервере PHP < 5.5

      // загружаем для всех пхп сфинкс
      $ echo "extension=sphinx.so" | sudo tee /etc/php5/conf.d/sphinx.ini
      // перезапуск апача
      $ sudo service apache2 restart
      // или php5-fpm
      $ sudo /etc/init.d/php5-fpm restart
       

      или PHP >= 5.5

      $ echo "extension=sphinx.so" | sudo tee /etc/php5/mods-available/sphinx.ini
      // для апача
      $ sudo ln -s /etc/php5/mods-available/sphinx.ini /etc/php5/apache2/conf.d/20-sphinx.ini
      // для php5-cli:
      $ sudo ln -s /etc/php5/mods-available/sphinx.ini /etc/php5/cli/conf.d/20-sphinx.ini
      
      // перезапуск апача
      $ sudo service apache2 restart
       

      Не удавалось запустить индексацию данных rotate т.к. процесс был запущен под root , таким образом: sudo /etc/init.d/sphinxsearch start, без судо не работало, выдает ERROR. Решение оказалось таким: процесс для сфинкса запускается при вызове комманды searchd и запускается именно под тем пользователем, под которым надо, далее все индексы обновляются и т.д. от этого пользователя.

Просмотр 0 веток ответов
  • Для ответа в этой теме необходимо авторизоваться.
×