Тип поиска: как, полный текст или комбинированный?


48

В чем разница между различными типами поиска?

  • подобно
  • Полный текст
  • комбинированный

Меня особенно интересует, как меняется поведение и производительность поиска для этих настроек.

Ответы:


63

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


подобно

Метод поиска на основе ключевых слов, разбивая ваш запрос на отдельные слова. Смотрите следующее из строки 326 в классеMage_CatalogSearch_Model_Resource_Fulltext::prepareResult()

            $words = Mage::helper('core/string')->splitWords($queryText, true, $query->getMaxQueryWords());
            foreach ($words as $word) {
                $like[] = $helper->getCILike('s.data_index', $word, array('position' => 'any'));
            }
            if ($like) {
                $likeCond = '(' . join(' OR ', $like) . ')';
            }

Вы можете видеть, что оно разбивает каждое слово в вашем поисковом запросе и объединяет их вместе в операторах LIKE - в итоге получается что-то вроде этого:

WHERE `attribute` LIKE 'my' OR `attribute` LIKE 'search' OR `attribute` LIKE 'query'

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


Полный текст

Поиск, основанный на релевантности - каждый поисковый запрос оценивается в соответствии с оценкой, назначенной на основе запроса MATCH ... AGAINST в MySQL . Вы можете увидеть это в действии в Mage_CatalogSearch_Model_Resource_Helper_Mysql4строке 44:

public function chooseFulltext($table, $alias, $select)
{
    $field = new Zend_Db_Expr('MATCH ('.$alias.'.data_index) AGAINST (:query IN BOOLEAN MODE)');
    $select->columns(array('relevance' => $field));
    return $field;
}

Таблица базы данных, которую Magento использует при выполнении полнотекстового поиска catalogsearch_fulltext. Пример значения:

EmCO0014e|Emma Certified|Emma Certified Organic Herbal Tonic Mist TRIAL/TRAVEL|Australian|Certified Organic|Palm Oil Free|Nut Free|Vegan Suitable|

Эти значения напрямую связаны с атрибутами, которые вы указали как «Использовать в быстром поиске» в Каталоге> Атрибуты> Управление атрибутами


скомбинировать

Довольно понятно. Взгляните на строку 354 из Mage_CatalogSearch_Model_Resource_Fulltext :

        if ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
                $where .= ($where ? ' OR ' : '') . $likeCond;
        } elseif ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE) {
            $select->columns(array('relevance'  => new Zend_Db_Expr(0)));
            $where = $likeCond;
        }

Вы можете видеть, что он просто добавляет LIKE результаты после возвращения результатов FULLTEXT.


Что нужно отметить

  1. Я настоятельно рекомендую использовать FULLTEXT для лучшей производительности и соответствующих результатов
  2. Просмотрите каждый атрибут и подумайте, нужно ли добавлять его в полнотекстовый индекс («Использовать в быстром поиске»).
  3. По умолчанию описания продуктов включены в индексацию FULLTEXT. Я почти всегда удаляю описания, поскольку они загрязняют оценки релевантности словами, используемыми в нерелевантных контекстах.
  4. Убедитесь, что ваши мета-атрибуты используются в полнотекстовом индексе. Заполните их содержательным содержанием.
  5. MySQL FULLTEXT имеет некоторые причуды - у него есть список игнорируемых слов, которые могут быть проблематичными, если названия ваших продуктов состоят из этих слов!
  6. MySQL по умолчанию игнорирует запросы FULLTEXT длиной до 4 символов . Атрибуты с короткими значениями будут игнорироваться, если вы не измените это значение.

Вы можете обойти пункты 5 и 6, используя метод Combine - результаты LIKE должны компенсировать любые слова, игнорируемые FULLTEXT.


7

Поисковый запрос «лайк» выполняет обычное совпадение с использованием запроса «% ключевое слово%». Одним из преимуществ этого типа поиска является то, что он будет соответствовать частичным словам. Это имеет серьезные недостатки, хотя:

  • быстро станет проблемой производительности
  • актуальность это плохо. На самом деле нет понятия «релевантность» в подобных запросах.

Полнотекстовый поиск будет работать с использованием полнотекстового поиска MyISAM ( http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html ). Вы должны прочитать об этом, но в двух словах:

  • производительность лучше
  • он исключит стоп-слова (например, "и", "с" и т. д.)
  • По умолчанию каждому результату присваивается оценка по релевантности.

Недостаток полного текста заключается в том, что он не может выполнять частичные совпадения, то есть поиск по запросу «pho» не найдет «телефон»

«Комбинированный» поиск будет использовать «подобное» условие для сопоставления результатов, но также будет учитывать полнотекстовый поиск для их сортировки. Это означает, что вы получите больше результатов (как, например, поиск будет выполнять частичные совпадения), и они также будут упорядочены лучше благодаря полнотекстовой оценке.

Как говорили другие люди, если вы серьезно относитесь к поиску, вы должны использовать Solr. Это намного быстрее и намного более актуально. Вы должны были бы иметь Magento EE и установить Solr самостоятельно, хотя.


1
Спасибо за этот ответ. Зачем мне нужен Magento EE?
PiTheNumber

1
Поиск Solr является частью Magento Enterprise (не является функцией сообщества). Существуют расширения, которые будут реализовывать поиск в сообществе, такие как magentocommerce.com/magento-connect/solr-bridge-search.html . Я не использовал их, хотя.
Пол Григорута,

6

Это прямые ссылки на тип запроса, который Magento будет использовать. Лично я считаю, что полнотекстовый поиск более эффективен, а производительность лучше, особенно если LIKE используется с подстановочными знаками (%). Сочетание обоих, вероятно, будет наиболее точным, но может оказаться излишним. Я бы придерживался полного текста.

Но если вы ищете мощное решение для поиска, проверьте этот проект: https://code.google.com/p/magento-solr/ . SOLR был создан для поиска больших коллекций, и хотя его реализация может занять некоторое время, оно того стоит. Лично я никогда не использовал его в Magento раньше, но в других проектах PHP он работал очень хорошо.

Полнотекстовую документацию можно найти здесь: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html. LIKE документация здесь: http://dev.mysql.com/doc/refman/5.0. /en/string-comparison-functions.html


Полный текст более мощный, но требует настроек в my.cnf, если он собирается давать результаты для слов длиной менее 5 или 4 символов, в зависимости от настроек по умолчанию. Подобно тому, как поиск часто прерывается, и его логику нужно изменить с ИЛИ на И, чтобы он не выдавал слишком много ненужных результатов.
Fiasco Labs

Вы правы насчет полного текста. Всегда разумно использовать хостинг на VPS или в компании, предлагающей хостинг Magento. Опции, такие как полнотекстовая конфигурация, должны быть доступны тогда или, по крайней мере, вы можете установить их самостоятельно. Есть ли у вас предложения по поиску сторонних разработчиков @Fiasco Labs?
Сандер Мангель

@FiascoLabs, как вы измените ORк AND?
Майкл Ягер

3

Проблема с LIKE в том, что он использует «% term%» по умолчанию. Я изменил его, чтобы он соответствовал термину «%» (обратите внимание на пробел перед термином), чтобы он соответствовал началу слов. Я также отсекал последние слова в поисковом запросе, чтобы «автомобили» давали те же результаты, что и «машина». Очевидно, что это не помогает с неправильными существительными, такими как «дети», но в любом случае это значительное улучшение.

Самым большим необъяснимым бессмысленным ходом Magento является использование поиска «ИЛИ» вместо «И». Если вы будете искать «красные машины», вы получите все красное (включая машины, собак, вилок, горные склоны и т. Д.) И все виды автомобилей (включая красные, синие, зеленые, желтые и т. Д.). С «И» вы получаете только те элементы, которые содержат «красный» И «автомобиль», именно так должен работать поиск !

Цитируя ответ jharrison.au, измените это:

if ($like) {
                $likeCond = '(' . join(' OR ', $like) . ')';
            }

К этому:

if ($like) {
                $likeCond = '(' . join(' AND ', $like) . ')';
            }

Чтобы сразу же получить значительный прирост релевантности результатов поиска.

Для множественного числа, вы можете отрубить последние буквы слова:

$words = Mage::helper('core/string')->splitWords($queryText, true, $query->getMaxQueryWords());
$words = array_walk($words,function(&$value, &$key) { 
    // use substr(...) instead of rtrim($value,'s') 
    // because rtrim will remove multiple esses
    $value = (substr($value,-1,1) === 's') ? substr($value,0,strlen($value - 1)) : $value;
});
foreach ($words as $word) {
       $like[] = $helper->getCILike('s.data_index', $word, array('position' => 'start')); // note I changed this to 'start'
}

В app/code/local/Mage/Core/Model/Resource/Helper/Abstract.phpвы можете переопределить основной файл и измените public function escapeLikeValue($value, $options = array())как быстрый ярлык, хотя рекомендуется способ сделать то же самое в модуле. Но вот оно.

Под if (isset($options['position'])) {есть переключатель. Я изменил регистры для «start» и «end», чтобы добавить пробелы до и после значения:

 case 'start':
      $value = '% ' . $value . '%'; // added '% ' . before
      // $value = $value . '%'; // core way (bad way)
      break;
 case 'end':
      $value = '%' . $value . ' %'; // added . ' %' after
      // $value = '%' . $value; // core way (bad way)
      break;

Чтобы пробелы до / после работали, вам, вероятно, также придется изменить способ построения поискового индекса, как я сделал, чтобы он гарантировал наличие пробела до и после каждого слова. Способ построения индекса по умолчанию состоит в том, чтобы отделить каждое поле с помощью '|' (символ трубы), например, «синий | автомобиль | очень хороший автомобиль» для индексации цвета, типа продукта, описания продукта. Но у моего индекса есть «синий | автомобиль | очень хороший автомобиль». Вы даже можете изменить структуру поискового индекса так, чтобы, возможно, слова, переносимые через дефис, заменялись («супер-быстрая машина» становится «супер-быстрой машиной») и т. Д. И т. Д.

Взять пример из ответа jharrison.au, где поле индекса поиска по умолчанию будет выглядеть так:

EmCO0014e|Emma Certified|Emma Certified Organic Herbal Tonic Mist TRIAL/TRAVEL|Australian|Certified Organic|Palm Oil Free|Nut Free|Vegan Suitable|

Мой будет выглядеть так:

 EmCO0014e | Emma Certified | Emma Certified Organic Herbal Tonic Mist TRIAL / TRAVEL | Australian | Certified Organic | Palm Oil Free | Nut Free | Vegan Suitable | 

(обратите внимание на пробелы перед и после каждого "|" и "/" и пробел перед самым первым словом)


1
Вы упомянули, чтобы переопределить app/code/local/Mage/Core/Model/Resource/Helper/Abstract.php. Этот файл не используется нигде, кроме функции поиска?
amitshree

1
@amitshree Хороший вопрос. Я не знаю, с головой. Полагаю, он может быть использован любым модельным ресурсом для результатов поиска. Но это действительно специально для экранирования LIKEв поисковых запросах SQL, и где еще Magento ищет, кроме как в поисковом индексе продукта? Я сделал это изменение более 2 лет назад на производственной площадке, и мы не нашли никаких ошибок, связанных с этим вообще. Все, что он на самом деле делает, - это делает так, чтобы у «начала слова» был пробел перед ним, а у «конца слова» - пробел после. Отдельно в индексе я проверяю, чтобы вокруг каждого слова были пробелы.
Баттл Буткус

2

Ничего из вышеперечисленного, используйте встроенную поисковую систему Zend Lucene, установив что-то вроде Blast Lucene Search или Extendeware Lucene Search. Соответствие превосходит любое предложение MySQL.

Да, я прошел все итерации по принятому ответу, но, честно говоря, поиска в Optimized Stock Magento по-прежнему крайне не хватало.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.