Type de recherche: Like, Full Text ou Combined?

48

Quelle est la différence entre les différents types de recherche?

  • Comme
  • Texte intégral
  • Combiné

Je suis particulièrement intéressé par la façon dont le comportement de recherche et les performances changent pour ces paramètres.

PiTheNumber
la source

Réponses:

63

Tout le monde se plaint toujours de la recherche Magento, mais je pense que cela peut très bien fonctionner si vous passez du temps à la planifier et à la configurer correctement.


Comme

Méthode de recherche basée sur les mots clés, divisant votre requête en mots individuels. Voir ce qui suit de la ligne 326 en classeMage_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) . ')';
            }

Vous pouvez voir qu'il divise chaque mot de votre requête de recherche et les assemble dans des instructions LIKE - vous obtenez quelque chose comme ceci:

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

Cette méthode peut fonctionner pour certaines configurations de magasin où les noms de produits sont simples et les clients recherchent des articles très spécifiques, mais selon mon expérience, ce n'est pas un bon choix.


Texte intégral

Recherche basée sur la pertinence - chaque requête de recherche est notée selon un score attribué en fonction de la requête MATCH ... AGAINST de MySQL . Vous pouvez voir ceci en action à la Mage_CatalogSearch_Model_Resource_Helper_Mysql4ligne 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;
}

La table de base de données utilisée par Magento lors de recherches en texte intégral est catalogsearch_fulltext. Un exemple de valeur:

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

Ces valeurs sont directement liées aux attributs spécifiés sous "Utiliser dans la recherche rapide" sous Catalogue> Attributs> Gérer les attributs.


Combiner

Assez explicite. Jetez un coup d'œil à la ligne 354 de 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;
        }

Vous pouvez voir qu'il ajoute simplement les résultats LIKE après le retour des résultats FULLTEXT.


Choses à noter

  1. Je recommande fortement d'utiliser FULLTEXT pour de meilleures performances et des résultats pertinents
  2. Parcourez chaque attribut et déterminez s'il est nécessaire ou non de l'ajouter à l'index du texte intégral ("Utiliser dans la recherche rapide").
  3. Par défaut, les descriptions de produits sont incluses dans l'indexation FULLTEXT. Je supprime presque toujours les descriptions car elles polluent les scores de pertinence avec des mots utilisés dans des contextes non pertinents.
  4. Assurez-vous que vos méta-attributs sont utilisés dans l'index du texte intégral. Remplissez-les avec un contenu significatif.
  5. MySQL FULLTEXT a quelques bizarreries - il a une liste de mots ignorés qui peuvent être problématiques si vos noms de produits sont composés de ces mots!
  6. Par défaut, MySQL ignore les requêtes FULLTEXT de moins de 4 caractères . Les attributs avec des valeurs courtes seront ignorés à moins que vous ne changiez cette valeur.

Vous pouvez contourner les points 5 et 6 en utilisant la méthode Combiner - les résultats LIKE doivent compenser les mots ignorés par FULLTEXT.

jharrison.au
la source
7

La recherche "like" fera la correspondance habituelle, en utilisant une requête similaire "% keyword%". L'un des avantages de ce type de recherche est qu'il va correspondre aux mots partiels. Il a cependant de sérieux inconvénients:

  • deviendra rapidement un problème de performance
  • la pertinence est mauvaise. Il n'y a en réalité aucun concept de "pertinence" dans les requêtes similaires

La recherche en texte intégral fonctionnera à l'aide de la recherche en texte intégral MyISAM ( http://dev.mysql.com/doc/refman/5.0/fr/fulltext-search.html ). Vous devriez lire à ce sujet, mais en quelques mots:

  • la performance est meilleure
  • il exclut les mots vides (comme "et", "avec" etc)
  • Il attribuera un score par défaut à chaque résultat en fonction de sa pertinence.

L'inconvénient du texte intégral est qu'il ne peut pas effectuer de correspondances partielles, c'est-à-dire qu'une recherche sur "pho" ne trouvera pas "téléphone"

La recherche "combinée" utilisera une condition "similaire" pour faire correspondre les résultats, mais prendra également en compte le score de recherche de texte intégral pour les trier. Cela signifie que vous obtiendrez plus de résultats (tout comme la recherche effectuera également des correspondances partielles) et qu'ils seront également mieux ordonnés en raison du score en texte intégral.

Comme d'autres personnes l'ont dit, si vous êtes sérieux au sujet de la recherche, vous devriez utiliser Solr. C'est beaucoup plus rapide et beaucoup plus pertinent. Cependant, vous devrez posséder Magento EE et installer Solr vous-même.

Paul Grigoruta
la source
1
Merci pour cette réponse. Pourquoi aurais-je besoin de Magento EE?
PiTheNumber
1
La recherche Solr fait partie de Magento Enterprise (pas une fonctionnalité de la communauté). Il existe des extensions qui implémenteront la recherche dans la communauté, telles que magentocommerce.com/magento-connect/solr-bridge-search.html . Je ne les ai pas utilisés cependant.
Paul Grigoruta
6

Ce sont des références directes au type de requête que Magento utilisera. Personnellement, je pense que la recherche en texte intégral est plus puissante et que les performances sont meilleures, en particulier si LIKE est utilisé avec des caractères génériques (%). Une combinaison des deux sera probablement la plus précise, mais pourrait être exagérée. Je m'en tiendrai au texte intégral.

Mais si vous recherchez une solution de recherche performante, consultez ce projet: https://code.google.com/p/magento-solr/ . SOLR a été conçu pour la recherche de grandes collections et sa mise en œuvre devrait prendre un certain temps, mais elle en vaut la peine. Personnellement, je ne l'avais jamais utilisé auparavant dans Magento, mais dans d'autres projets PHP, il fonctionnait très bien.

La documentation en texte intégral est disponible à l' adresse suivante : http://dev.mysql.com/doc/refman/5.0/fr/fulltext-search.html La documentation LIKE est disponible à l' adresse suivante : http://dev.mysql.com/doc/refman/5.0 /fr/string-comparison-functions.html

Sander Mangel
la source
Le texte intégral est plus puissant, mais nécessite des configurations dans my.cnf pour donner des résultats pour les mots de moins de 5 ou 4 caractères, selon la configuration par défaut. Comme la recherche, elle est souvent expédiée en panne et doit avoir sa logique modifiée de OR à AND pour ne pas générer trop de résultats non pertinents.
Fiasco Labs
Vous avez raison à propos du texte intégral. Il est toujours judicieux d’héberger sur un serveur VPS ou avec une entreprise proposant un hébergement Magento. Des options telles que la configuration Fulltext devraient alors être disponibles ou vous pouvez au moins les définir vous-même. Avez-vous des suggestions de recherche de tierces parties @Fiasco Labs?
Sander Mangel
@ FiascoLabs, comment changez-vous le ORen AND?
Michael Yaeger
3

Le problème avec LIKE est qu'il utilise "% term%" par défaut. Je l'ai changé pour correspondre à "terme%" (notez l'espace avant le terme), afin qu'il corresponde au début des mots. J'ai également découpé le terme 's' dans un terme de recherche afin que "cars" donne les mêmes résultats que "car". De toute évidence, cela n’aide en rien les noms irréguliers comme "enfants", mais c’est quand même une grande amélioration.

Le plus grand mouvement inexplicablement absurde de Magento consiste à utiliser la recherche "OU" au lieu de "ET". Si vous recherchez "voitures rouges", vous obtiendrez tout le rouge (y compris les voitures, les chiens, les fourches, les flancs de la montagne, etc.) et tous les types de voitures (y compris les rouges, les bleues, les vertes, les jaunes, etc.). Avec "ET", vous n’obtenez que les éléments qui contiennent "rouge" ET "voiture", c’est ainsi que la recherche devrait fonctionner!

Citant la réponse de jharrison.au, changez ceci:

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

Pour ça:

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

Pour obtenir un coup de pouce immédiat et massif pour la pertinence de vos résultats de recherche.

Au pluriel, vous pouvez découper le "s" final d'un mot comme celui-ci:

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

Dans app/code/local/Mage/Core/Model/Resource/Helper/Abstract.phpvous pouvez remplacer le fichier de base et changer le public function escapeLikeValue($value, $options = array())comme un raccourci rapide, bien que la façon conseillée est de faire la même chose dans un module. Mais le voici.

Sous if (isset($options['position'])) {il y a un interrupteur. J'ai changé les cas pour 'début' et 'fin' pour ajouter des espaces avant et après la valeur:

 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;

Pour que les espaces avant / après fonctionnent, vous devez probablement aussi changer la façon dont l'index de recherche est construit, comme je l'ai fait, afin qu'il s'assure qu'il y a un espace avant et après chaque mot. Le moyen par défaut de construire l’index est de séparer chaque champ par un '|' (caractère de pipe), par exemple "blue | car | une très belle voiture" pour indexer la couleur, le type de produit, la description du produit. Mais mon index a "blue | car | une très belle voiture". Vous pouvez même modifier la construction de l'index de recherche de manière à remplacer les mots composés d'un trait d'union ("voiture ultra-rapide" devenant "voiture super rapide"), etc., etc.

Emprunter un exemple dans la réponse de jharrison.au, où un champ d'index de recherche par défaut ressemblerait à ceci:

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

Le mien ressemblerait à ceci:

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

(notez les espaces avant et après chaque "|" et "/", et un espace avant le tout premier mot)

Buttle Butkus
la source
1
Vous avez parlé de remplacer app/code/local/Mage/Core/Model/Resource/Helper/Abstract.php. Ce fichier n'est pas utilisé ailleurs que dans la fonctionnalité de recherche?
amitshree
1
@amitshree Bonne question. Je ne sais pas par coeur. Je suppose que cela pourrait être utilisé par n'importe quelle ressource modèle pour les résultats de recherche. Mais c'est vraiment spécifiquement pour échapper LIKEaux requêtes de recherche SQL, et où Magento peut-il chercher ailleurs que dans l'index de recherche de produit? J'ai apporté ce changement il y a plus de 2 ans sur un site de production et nous n'avons trouvé aucun bogue lié à cela. Tout ce que cela fait réellement, c’est que le "début du mot" doit avoir un espace devant lui et que "la fin du mot" doit avoir un espace après. Séparément, dans l'index, je m'assure que chaque mot est entouré d'espaces.
Buttle Butkus
2

Aucune de ces solutions, utilisez le moteur de recherche intégré Zend Lucene en installant quelque chose comme Blast Lucene Search ou Extendeware Lucene Search. La pertinence dépasse toutes les offres MySQL.

Oui, j'ai parcouru toutes les versions de la réponse acceptée, mais franchement, la recherche optimisée pour Magento Stock faisait toujours cruellement défaut.

Lucene, d’autre part, fournit et est déjà inclus dans l’installation de Magento, il lui faut juste un module pour l’activer.

Fiasco Labs
la source