Rodzaj wyszukiwania: polub, pełny tekst czy kombinacja?

48

Jaka jest różnica między różnymi typami wyszukiwania?

  • Lubić
  • Pełny tekst
  • Łączny

Szczególnie interesuje mnie zmiana sposobu wyszukiwania i wydajności tych ustawień.

PiTheNumber
źródło

Odpowiedzi:

63

Wszyscy zawsze narzekają na wyszukiwanie Magento, ale uważam, że może on działać naprawdę dobrze, jeśli poświęcisz czas na prawidłowe planowanie i konfigurowanie.


Lubić

Metoda wyszukiwania oparta na słowach kluczowych, dzieląca zapytanie na pojedyncze słowa. Zobacz, co następuje z wiersza 326 w klasieMage_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) . ')';
            }

Możesz zobaczyć, że dzieli każde słowo w zapytaniu i łączy je razem w instrukcjach LIKE - w efekcie powstaje coś takiego:

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

Ta metoda może działać w przypadku niektórych konfiguracji sklepu, w których nazwy produktów są proste, a klienci szukają bardzo konkretnych produktów, ale z mojego doświadczenia nie jest to dobry wybór.


Pełny tekst

Wyszukiwanie oparte na trafności - każde zapytanie wyszukiwania jest oceniane zgodnie z wynikiem przypisanym na podstawie zapytania MATCH ... PRZECIWKO MySQL . Możesz to zobaczyć w akcji w Mage_CatalogSearch_Model_Resource_Helper_Mysql4wierszu 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;
}

Tabela bazy danych, z której korzysta Magento podczas wyszukiwania pełnotekstowego, to catalogsearch_fulltext. Przykładowa wartość:

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

Te wartości są bezpośrednio powiązane z atrybutami określonymi jako „Użyj w szybkim wyszukiwaniu” w katalogu> Atrybuty> Zarządzaj atrybutami


Połączyć

Dość oczywiste. Spójrz na linię 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;
        }

Możesz to zobaczyć, po prostu dodaje wyniki LIKE po powrocie wyników FULLTEXT.


Warto zwrócić uwagę

  1. Zdecydowanie polecam użycie FULLTEXT, aby uzyskać lepszą wydajność i odpowiednie wyniki
  2. Przejrzyj każdy atrybut i zastanów się, czy konieczne jest dodanie go do indeksu pełnotekstowego („Użyj w szybkim wyszukiwaniu”)
  3. Domyślnie opisy produktów są uwzględnione w indeksowaniu FULLTEXT. Prawie zawsze usuwam opisy, ponieważ zanieczyszczają one wyniki trafności słowami używanymi w nieistotnych kontekstach.
  4. Upewnij się, że atrybuty meta są używane w indeksie pełnotekstowym. Wypełnij je znaczącą treścią.
  5. MySQL FULLTEXT ma pewne dziwactwa - ma listę ignorowanych słów, które mogą być problematyczne, jeśli nazwy produktów składają się z tych słów!
  6. MySQL domyślnie ignoruje zapytania FULLTEXT o długości poniżej 4 znaków . Atrybuty z krótkimi wartościami będą ignorowane, chyba że zmienisz tę wartość.

Możesz obejść punkty 5 i 6 za pomocą metody Połącz - wyniki PODOBNE do powinny zrekompensować wszelkie ignorowane słowa FULLTEXT.

jharrison.au
źródło
7

Wyszukiwanie „jak” wykona zwykłe dopasowanie podobne, przy użyciu zapytania typu „% keyword%”. Zaletą tego rodzaju wyszukiwania jest to, że będzie pasować do słów częściowych. Ma jednak poważne wady:

  • szybko stanie się problemem z wydajnością
  • trafność jest zła. W rzeczywistości nie ma pojęcia „trafności” w podobnych zapytaniach

Wyszukiwanie pełnotekstowe będzie działać przy użyciu wyszukiwania pełnotekstowego MyISAM ( http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html ). Powinieneś o tym przeczytać, ale w skrócie:

  • wydajność jest lepsza
  • wykluczy stopery (takie jak „i”, „z” itp.)
  • Domyślnie przypisze ocenę do każdego wyniku na podstawie trafności

Wadą pełnego tekstu jest to, że nie można wykonać częściowych dopasowań, tzn. Wyszukiwanie „pho” nie znajdzie „telefonu”

Wyszukiwanie „połączone” użyje warunku „podobnego” do dopasowania wyników, ale weźmie również pod uwagę wynik wyszukiwania pełnotekstowego podczas sortowania. Oznacza to, że uzyskasz więcej wyników (podobnie jak wyszukiwanie spowoduje częściowe dopasowania), a także będą lepiej uporządkowane ze względu na wynik pełnego tekstu.

Jak powiedzieli inni, jeśli poważnie myślisz o wyszukiwaniu, powinieneś używać Solr. Jest znacznie szybszy i znacznie bardziej odpowiedni. Musisz jednak posiadać Magento EE i sam zainstalować Solr.

Paul Grigoruta
źródło
1
Dziękuję za tę odpowiedź. Dlaczego miałbym potrzebować Magento EE?
PiTheNumber
1
Wyszukiwanie Solr jest częścią Magento Enterprise (nie jest funkcją społeczności). Istnieją rozszerzenia, które zaimplementują wyszukiwanie w społeczności, takie jak magentocommerce.com/magento-connect/solr-bridge-search.html . Jednak ich nie użyłem.
Paul Grigoruta,
6

Są to bezpośrednie odniesienia do typu zapytania, którego użyje Magento. Osobiście uważam, że wyszukiwanie pełnotekstowe jest bardziej wydajne, a wydajność lepsza, szczególnie jeśli LIKE jest używane z symbolami wieloznacznymi (%). Połączenie obu będzie prawdopodobnie najdokładniejsze, ale może być przesadą. Trzymałbym się pełnego tekstu.

Ale jeśli szukasz wydajnego rozwiązania wyszukiwania, sprawdź ten projekt: https://code.google.com/p/magento-solr/ . SOLR został stworzony do przeszukiwania dużych kolekcji i chociaż wdrożenie go może zająć trochę czasu, powinno być tego warte. Osobiście nigdy wcześniej nie korzystałem z niego w Magento, ale w innych projektach PHP działał bardzo dobrze.

Pełną dokumentację tekstową można znaleźć tutaj: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html Dokumentację LIKE tutaj: http://dev.mysql.com/doc/refman/5.0 /en/string-comparison-functions.html

Sander Mangel
źródło
Pełny tekst jest mocniejszy, ale wymaga konfiguracji w my.cnf, jeśli ma dać wyniki dla słów mniejszych niż 5 lub 4 znaki, w zależności od domyślnej konfiguracji. Ponieważ wyszukiwanie często jest wysyłane zepsute i jego logika musi zostać zmieniona z OR na AND, więc nie wyrzuca zbyt wielu niepotrzebnych wyników.
Fiasco Labs
Masz rację co do pełnego tekstu. Zawsze jest mądry do hostowania na VPS lub w firmie oferującej hosting Magento. Opcje takie jak konfiguracja pełnego tekstu powinny być wtedy dostępne lub przynajmniej możesz je ustawić samodzielnie. Czy masz jakieś sugestie dotyczące wyszukiwania stron trzecich @Fiasco Labs?
Sander Mangel
@FiascoLabs, jak można zmienić ORsię AND?
Michael Yaeger
3

Problem z LIKE polega na tym, że domyślnie używa on „% term%”. Zmieniłem go, by pasował do „terminu%” (zwróć uwagę na spację przed terminem), aby pasował do początków słów. Odciąłem też finałowe „s” w wyszukiwanym haśle, aby „samochody” dały takie same wyniki, jak „samochód”. Oczywiście nie pomaga to w przypadku rzeczowników nieregularnych, takich jak „dzieci”, ale i tak jest to ogromna poprawa.

Największym niewytłumaczalnym nonsensownym posunięciem Magento jest użycie wyszukiwania „LUB” zamiast „AND”. Jeśli przeszukujesz „czerwone samochody”, dostaniesz wszystko na czerwono (w tym samochody, psy, widelce, zbocza gór itp.) I każdy rodzaj samochodu (w tym czerwony, niebieski, zielony, żółty itp.). Z „AND” otrzymujesz tylko przedmioty, które zawierają „czerwony” ORAZ „samochód”, i tak powinno działać wyszukiwanie !

Cytując odpowiedź jharrison.au, zmień to:

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

Do tego:

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

Aby uzyskać natychmiastowy, ogromny wzrost trafności wyników wyszukiwania.

W przypadku liczby mnogiej możesz odciąć ostatnie „s” słowa takiego:

$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'
}

W app/code/local/Mage/Core/Model/Resource/Helper/Abstract.phpmożna zastąpić plik podstawowy i zmienić go public function escapeLikeValue($value, $options = array())jako szybki skrót, chociaż zaleca się zrobienie tego samego w module. Ale oto jest.

Pod if (isset($options['position'])) {jest przełącznik. Zmieniłem przypadki „start” i „end”, aby dodać spacje przed i po wartości:

 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;

Aby spacje przed / po zadziałały, prawdopodobnie musisz również zmienić sposób budowania indeksu wyszukiwania, tak jak ja, aby upewniał się, że przed każdym słowem i po nim jest spacja. Domyślnym sposobem budowania indeksu jest oddzielenie każdego pola znakiem „|” (znak rury), np. „niebieski | samochód | bardzo ładny samochód” do indeksowania koloru, typu produktu, opisu produktu. Ale mój indeks ma „niebieski | samochód | bardzo ładny samochód”. Możesz nawet zmodyfikować budowę indeksu wyszukiwania, aby być może słowa z łącznikami zostały zastąpione („superszybki samochód” staje się „superszybkim samochodem”) itp. Itp.

Pożyczanie egzaminu z odpowiedzi jharrison.au, gdzie domyślne pole indeksu wyszukiwania wyglądałoby tak:

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

Mój wyglądałby tak:

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

(zwróć uwagę na spacje przed i po każdym „|” i „/” oraz spację przed pierwszym słowem)

Buttle Butkus
źródło
1
Wspomniałeś o zastąpieniu app/code/local/Mage/Core/Model/Resource/Helper/Abstract.php. Ten plik nie jest używany nigdzie indziej niż funkcja wyszukiwania?
amitshree,
1
@amitshree Dobre pytanie. Nie wiem od czubka głowy. Podejrzewam, że może być wykorzystywany przez dowolny zasób modelu do wyszukiwania. Ale tak naprawdę jest to szczególnie ucieczka LIKEw zapytaniach SQL, a gdzie jeszcze Magento szuka poza indeksem wyszukiwania produktu? Dokonałem tej zmiany ponad 2 lata temu na stronie produkcyjnej i nie znaleźliśmy żadnych błędów z tym związanych. Wszystko, co tak naprawdę robi, polega na tym, aby „początek słowa” musiał mieć przed sobą spację, a „koniec słowa” musiał mieć spację po nim. Osobno w indeksie upewniam się, że każde słowo ma spacje wokół niego.
Buttle Butkus,
2

Żadnego z powyższych, użyj wbudowanej wyszukiwarki Zend Lucene, instalując coś takiego jak Blast Lucene Search lub Extendeware Lucene Search. Trafność przewyższa każdą ofertę MySQL.

Tak, przeszedłem wszystkie iteracje dla zaakceptowanej odpowiedzi, ale szczerze mówiąc, nadal nie było optymalnego wyszukiwania w Magento.

Z drugiej strony Lucene dostarcza i jest już uwzględniona w instalacji Magento, potrzebuje tylko modułu, aby ją włączyć.

Fiasco Labs
źródło