Sphinx и поиск похожих записей

Тема в разделе "Базы данных", создана пользователем KillDead, 25 дек 2015.

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

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    Здравствуйте. Есть БД с короткими записями. К примеру Заголовки новостей, Названия товаров , Ключи и тп. Задача - найти похожие записи.
    Тут в паре соседних тем речь касалась подобного. Для пробы взял 10к названий товаров, по ним легко сказать похожие они в реальности или нет.
    Товар мышка. Забил в поиск 1000dpi usb 1 1 wired ergonomic optical mouse 150cm cable
    Среди первых 30
    Для полнотекстового поиска с помощью мускула - из 30 , 16 товаров именно из категории Мышки
    Для сфинска - из 30 только 10 - из категории мышки, другие- это провода, хабы и прочее. Попустил к примеру такие:
    A300 Human Ergonomic 6 Keys Bluetooth3.0 Wireless Optical Gaming Mouse for Home Office,
    RH1900 Wired Gaming Mouse USB Powered


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

    Сам запрос

    Код:
    SELECT * , WEIGHT() FROM keywords WHERE MATCH('"1000dpi usb 1 1 wired ergonomic optical mouse 150cm cable"/1') LIMIT 0,30 OPTION ranker = matchany , cutoff =1000
    Пробовал ещё поиграться с вхождениями, но результат вышел хуже
    Код:
    SELECT * , WEIGHT() FROM keywords WHERE MATCH('1000dpi | usb | wired | ergonomic | optical | mouse | 150cm | cable| *1000dpi* | *usb* | *wired* | *ergonomic* | *optical* | *mouse* | *150cm* | *cable*') LIMIT 0,30 OPTION cutoff =1000
    

    сам конфиг
    Код:
    source keywords
    {
        type            = mysql
         sql_host        = localhost
        sql_user        = root
        sql_pass        =
        sql_db        = search_index
        sql_port        = 3306
         sql_query_pre        = SET NAMES utf8
        sql_query        = \
            SELECT * \
            FROM keywords       
            sql_attr_uint    = name
    
    
    }
    index keywords
    {
         # Источник данных для индексирования
        source            = keywords
    
        # Адрес, где будут хранится данные индекса
        path            = D:\sphinx/data/keywords
    
    
        min_infix_len = 3
        min_word_len = 3
    
    
        # Кодировка
        #charset_type        = utf-8
    }
     
    Последнее редактирование: 26 дек 2015
    Anton нравится это.
  2. tuthanhamon

    tuthanhamon Создатель

    Регистр.:
    14 ноя 2015
    Сообщения:
    21
    Симпатии:
    6
    Полнотекстовый поиск <> интеллектуальный поиск. Если в строке поиска есть "150cm cable" и в названии какого-нить кабеля есть строка "150 sm cable", то было бы странно, если бы полнотекстовый поиск такую строку пропустил.

    Чтобы поисковый алгоритм "понимал", что он ищет именно мышку, а не трубу ПВХ и не кабель, - я бы для начала вводил систему категорий (скорее всего древовидную) и результатам из "своей" категории присваивал больший вес. Само собой, для начала надо определять, из какой категории искомый запрос - либо спрашивать пользователя, либо какими-то другими методиками. Например, если из первых 10 результатов большая часть - мышки, тогда предполагать что ищется именно она и соответственно пересортировать результат.

    В любом случае, хороший поиск - это то, на чем гугл зарабатывает миллиарды. Не думаете же вы, что это настолько просто и что любой может взять и закодить аналог? ;)
     
  3. Black Hat

    Black Hat Постоялец

    Регистр.:
    15 май 2015
    Сообщения:
    120
    Симпатии:
    80
  4. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    с категориями - думал. Ввести весовые коэфициенты и добавлять в зависимости от похожести категории это выход. Но как быть если категории не указаны - хз.
    Я не просил мегоинтелектуального поиска, я просил чтобы сфинкс искал не хуже чем работающий полнотектовый поиск у мускула. ибо он тупит. Как вариант был- нормализовать названия, вроде - обрезать все короткие символы и тп.

    Думал, а вообще есть где годные списки замен? Искал но не нашёл, самому добавить 1000+ словоформ проблематично, наверняка есть уже составленный список?
     
  5. Anton

    Anton ¯\_(ツ)_/¯

    Moderator
    Регистр.:
    28 авг 2007
    Сообщения:
    652
    Симпатии:
    639

    Я хз, но может поможет?) Перейти по ссылке
     
  6. Black Hat

    Black Hat Постоялец

    Регистр.:
    15 май 2015
    Сообщения:
    120
    Симпатии:
    80
    Подсказать не могу. Если есть словарь синонимов, наклепать с него :) В любом случае, для поиска wordforms пригодятся
    А что мешает взять мускул, и закешировать результаты? Если динамика - неужели настолько все плохо? Не совсем понятно - то ли в форме поиска это вбивается, то ли по существующим названиям формируется блок "похожее".
    Потом конфиг какой-то куцый
    1. charset_table - не указан, может быть цифры режет 1000dpi например
    2. Перейти по ссылке, чтобы не писать такой длинный "паровоз", а также ставим index_exact_words = 1 - думаю поможет :)
     
    Последнее редактирование: 30 дек 2015
    KillDead нравится это.
  7. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    нет, там простой никаких настроек нет)

    С кэшированием - дельная мысль, вообще я так и делаю, но динамика мешает, да и хотел убить двух зайцев - сделать и обычный поиск и поиск похожих. Вообще изначально у меня стоял вопрос о поиске похожих, то есть "Мышка 1000dpi usb 1 1 wired ergonomic optical mouse 150cm cable Смотрите ещё похожие товары .... "
    1. charset_table - спасибо попробую
    2. charset_table expand_keywords = 1 , index_exact_words = 1
    эти пробовал . Но с морфологией результаты становятся ещё ужаснее, мышки вообще уходят за вторую десятку)
     
  8. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    Здравствуйте. В прошлый раз более менее победил, надо было просто поднять параметр cutoff. Но сейчас вновь столкнулся с проблемой. Дело в том, что в поиске слишком много левых товаров.
    Взять опять ту же мышку :
    холодильник bosch
    В первых результатах будет
    Bosch Тостер Bosch TAT 6101 (900Вт)
    Просто потому что фирма встречается несколько раз и гораздо весомее. Думаю дело в настройке ранжирования. Пробовал поиграться с настройками Перейти по ссылке но успеха не добился, примерно 30% запросов выдают мусорные результаты.
    Какие у вас настройки и какой запрос к сфинксу?
     
  9. Black Hat

    Black Hat Постоялец

    Регистр.:
    15 май 2015
    Сообщения:
    120
    Симпатии:
    80
    Можно сделать чтобы матчил по всем словам SPH_MATCH_EXTENDED2 (холодильник | *холодильник*) & (bosch | *bosch*), если не найдет - по любому SPH_MATCH_ANY. Это 2 запроса к сфинксу.
    Чтобы "поискового спама" :) не было, можно Bosch Тостер Bosch TAT 6101 (900Вт) превратить в Bosch Тостер TAT 6101 (900Вт) - через отдельное поле в БД, через скрипт xmlpipe2 или как вам больше нравится.
     
    KillDead нравится это.
  10. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    Спасибо, насчёт фильтрации от повторов и левых слов в описании- делаю. Отдельно поля для поиска, отдельно для вывода.
    Мысль- искать вначале по полному совпадению тоже посещала. Но пока это сложновато в реализации для меня и 2 запроса вместо одного...
    Насчёт SPH_MATCH_ANY - на сервере почему то ограничение в cutoff. То есть если ставить 100000 и 1000000 результаты одинаковые и не самые лучшие , но на локалке результаты когда перебирается миллион -намного ревалентнее. Но наверняка на больших объёмах поисков это будет грузить серв.
    Сейчас уже написал минитулзу для работы над настройками сфинкса, но в итоге перешёл к тупому перебору. Пока SPH04 показал себя лучше на нечётких запросах, хотя всё равно 20% - УГ. Там в принципе и бм25 и вес более полным совпадениям придаётся больший.
     
    latteo нравится это.