MATCH AGAINST

Тема в разделе "Базы данных", создана пользователем new_forward, 17 ноя 2015.

Модераторы: latteo
  1. new_forward

    new_forward

    Регистр.:
    5 май 2008
    Сообщения:
    668
    Симпатии:
    44
    Доброго времени суток, как заставить искать MATCH (title) AGAINST то что нужно, например:

    При запросе 'Железный человек', выводится в первых рядах результата 'Человек паук' ?

    Делаю вот так:
    MATCH (title) AGAINST ('+Железный +человек')

    та же история :conf:
     
  2. HunterNNm

    HunterNNm Постоялец

    Регистр.:
    3 сен 2010
    Сообщения:
    53
    Симпатии:
    6
    Если есть возможность - ставьте и настраивайте sphinx. И в разы быстрее, и с релевантностью всё хорошо. На голом MySQL полнотекстовый поиск это порнография...
     
  3. new_forward

    new_forward

    Регистр.:
    5 май 2008
    Сообщения:
    668
    Симпатии:
    44
    Пытаюсь поставить sphinx выдает ошибку, что не хватает библиотек каких то, я так понимаю:

    rpm -Uvh http://sphinxsearch.com/files/sphinx-2.2.10-1.rhel6.x86_64.rpm

    Retrieving http://sphinxsearch.com/files/sphinx-2.2.10-1.rhel6.x86_64.rpm
    error: Failed dependencies:
    libcrypto.so.10()(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64
    libexpat.so.1()(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64
    libmysqlclient.so.16()(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64
    libmysqlclient.so.16(libmysqlclient_16)(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64
    libodbc.so.2()(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64
    libpq.so.5()(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64
    libssl.so.10()(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64
    libstdc++.so.6(GLIBCXX_3.4.10)(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64
    libstdc++.so.6(GLIBCXX_3.4.9)(64bit) is needed by sphinx-2.2.10-1.rhel6.x86_64

    Есть ли панацея, как их все разом поставить?
     
  4. Black Hat

    Black Hat Постоялец

    Регистр.:
    15 май 2015
    Сообщения:
    114
    Симпатии:
    76
  5. new_forward

    new_forward

    Регистр.:
    5 май 2008
    Сообщения:
    668
    Симпатии:
    44
    Спасибо, но я именно так и сделал перерыв интернет.

    Появилась проблема с поиском, другими словами чудеса происходят.

    Есть новость с название Ёлки лохматые, если искать просто Ёлки, то все находит, а если вместе Ёлки лохматые то апи php не выдает $result['matches'], но пишет Total results found: 8.

    Код вызова из PHP
    PHP:
    <?
    include (
    'sphinx_api.php');

    $cl = new SphinxClient();
    $page 3// our results page number
    $items_per_page 10// show 10 results per page
    $index_name 'mysqlbasename'// Index name to fetch from
    $request iconv("CP1251""UTF-8"'ёлки лохматые');
    $cl->SetServer"localhost"9312 ); // server, port
    $cl->SetConnectTimeout); // max connect timeout
    $cl->SetMaxQueryTime(1000); // max query timeout
    $cl->SetMatchModeSPH_MATCH_ALL  ); // ALL, ANY, PHRASE, EXTENDED...
    $cl->SetLimits(intval($page*$items_per_page), intval($items_per_page), 1000);
    $result $cl->Query$request$index_name );
    if ( 
    $result === false ) {
    if( 
    $cl->GetLastWarning() ) { // check for warnings
      
    echo 'WARNING: '.$cl->GetLastWarning();
      exit;
    }
    // no warnings found, result=FALSE
    exit('Cannot connect etc.');
    }

    echo 
    'Total results found: '.$result['total'];

    print_r($result);

    // Compose comma separated string with posts IDs
    foreach ($result['matches'] AS $key => $row)
            
    $ids_arr[] = intval($key);
            echo 
    $ids_csv implode(','$ids_arr);


    ?>
    Конфиг sphinx
    Код:
    # Настройки источника "mysqlbasename" с которого будем брать контент
    source mysqlbasename
    {
    type = mysql # тип источника, в данном случае БД MySQL
    sql_host = localhost # Хост MySQL
    sql_user = root # Пользователь MySQL
    sql_pass = root # Пароль MySQL
    sql_db = mysqlbasename # Название БД в MySQL
    sql_port = 3306 # Порт сервера MySQL
    sql_query_pre = SET NAMES cp1251 # Кодировка индексируемой таблицы
    sql_query_pre = SET CHARACTER SET cp1251
    sql_query_pre = SET CHARACTER_SET_RESULTS=utf8
    # Запрос которым делаем выборку всех записей, которые должны быть проиндексированы
    sql_query =  SELECT id, title  FROM dle_post
    }
    # настройки построения индекса с использованием источника "mysqlbasename"
    index mysqlbasename
    {
    source = mysqlbasename # Имя источника данных
    # Путь по которому будут сохранены файлы индекса, если индекс большой то можно <br>#  перенести на отдельный раздел или жесткий диск.
    path = /var/data/mysqlbasename
    # Настройка хранения значений атрибутов документов, extern - хранить раздельно по ID.
    docinfo = extern
    mlock = 0 # Бдокировка памяти для кеширования данных, 0 - нет.
    morphology = stem_en, stem_ru, soundex # набор морфологическиз препроцессоров для обработки.
    min_word_len = 3 # минисмальная длина слова для индексации
    html_strip = 1 # Чистить или нет HTML (1 - да)
    }
    # настройки индексатора
    indexer
    {
    mem_limit = 32M # лимит памяти для работы индексатора
    }
    # настройки поискового демона (SearchDaemon, searchD)
    searchd
    {
    listen = 9312 # порт для работы через API
    listen = 9306:mysql41 # порт для комуникаций с MySQL
    log = /var/log/searchd.log # логи демона
    query_log = /var/log/sphinx/query.log # логи поисковых запросов
    read_timeout = 5 # таймаут чтения в секундах
    client_timeout = 300 # таймаут поддержания соединения, между запросами в секундах
    max_children = 30 # Максимально допустимое количество порождаемых процессов
    pid_file = /var/log/searchd.pid # PID(ProcessID) файл родительского процесса
    seamless_rotate = 1 # предотвращает паралич search при работе с большим количеством кешируемых данных
    preopen_indexes = 0 # Откривать все индексы при запуске, 0 - нет
    unlink_old = 1 # чистка старых индексов, 1 - да
    mva_updates_pool = 1M # Резервируемый размер пула в ОЗУ для обновлений
    max_packet_size = 8M # Максимальный размер сетевого пакета для обмена данными
    max_filters = 256 # Максимальное количество фильтров что можно использовать на один запрос
    max_filter_values = 4096 # Макс. количество значений для одного фильтра
    }
    
    Вот что выводится : Total results found: 8 Array ( [error] => [warning] => [status] => 0 [fields] => Array ( [0] => title ) [attrs] => Array ( ) [total] => 8 [total_found] => 8 [time] => 0.000 [words] => Array ( [ёлк] => Array ( [docs] => 54 [hits] => 56 ) [лохмат] => Array ( [docs] => 13 [hits] => 14 ) ) )


    Может стоит какое то ограничение на запрос? потому что $result['matches'] не выводится когда запрос длиннее:

    Запрос - Ёлки, выводится
    Запрос - Ёлки лохматые, не выводится
    Запрос - Microsoft Visual, выводится
    Запрос - Microsoft Visual Studio, не выводится
     
    Последнее редактирование: 20 ноя 2015
  6. new_forward

    new_forward

    Регистр.:
    5 май 2008
    Сообщения:
    668
    Симпатии:
    44
    Дайте плиз пример, как можно например добиться результата как при поиске через LIKE например.
     
  7. new_forward

    new_forward

    Регистр.:
    5 май 2008
    Сообщения:
    668
    Симпатии:
    44
    УРА!!! разобрался.

    В общем нужно было с SetLimits поиграться. Вот итоговый вариант, ищет то что надо и на русском и английском.

    PHP:
    <?
    include (
    'sphinx_api.php');

    $cl = new SphinxClient();
    $index_name 'mysqlbasename'// Index name to fetch from
    $request 'ёлки лохматые';
    //$request = 'железный человек';
    //$request = 'Microsoft Visual Studio';
    $cl->SetServer"localhost"9312 ); // server, port
    $cl->SetConnectTimeout); // max connect timeout
    $cl->SetMaxQueryTime(1000); // max query timeout
    $cl->SetMatchModeSPH_MATCH_ALL ); // ALL, ANY, PHRASE, EXTENDED...
    $cl->SetLimits(01001000);
    $result $cl->Query$request$index_name );
    if ( 
    $result === false ) {
     if( 
    $cl->GetLastWarning() ) { // check for warnings
      
    echo 'WARNING: '.$cl->GetLastWarning();
      exit;
     }
     
    // no warnings found, result=FALSE
     
    exit('Cannot connect etc.');
    }

    echo 
    'Total results found: '.$result['total'];

    print_r($result);

    // Compose comma separated string with posts IDs
    foreach ($result['matches'] AS $key => $row)
      
    $ids_arr[] = intval($key);
         echo 
    $ids_csv implode(','$ids_arr);
       

    ?>
     
  8. Black Hat

    Black Hat Постоялец

    Регистр.:
    15 май 2015
    Сообщения:
    114
    Симпатии:
    76
    На заметку, Сфинкс понимает SQL, и к нему можно делать запросы вида
    Код:
    SELECT *, weight() AS `weight` FROM tiny_nutrition where match('$searchText') ORDER BY `weight` DESC, `carb` ASC LIMIT 100
    
     
  9. HunterNNm

    HunterNNm Постоялец

    Регистр.:
    3 сен 2010
    Сообщения:
    53
    Симпатии:
    6
    Я с ним только через SQL и общаюсь... Как по мне так самый удобный вариант.