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ń.
Jaka jest różnica między różnymi typami wyszukiwania?
Szczególnie interesuje mnie zmiana sposobu wyszukiwania i wydajności tych ustawień.
Odpowiedzi:
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.
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.
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_Mysql4
wierszu 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
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.
Możesz obejść punkty 5 i 6 za pomocą metody Połącz - wyniki PODOBNE do powinny zrekompensować wszelkie ignorowane słowa FULLTEXT.
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:
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:
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.
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
OR
się AND
?
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.php
moż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)
app/code/local/Mage/Core/Model/Resource/Helper/Abstract.php
. Ten plik nie jest używany nigdzie indziej niż funkcja wyszukiwania?
LIKE
w 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.
Ż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ć.