web-dev-qa-db-fra.com

Manière correcte d'utiliser la recherche en texte intégral MySQL sur une chaîne de mots clés?

J'ai une chaîne de mots clés sur laquelle je souhaite effectuer une recherche en texte intégral.

La requête de recherche actuelle dans le modèle est la suivante:

$jinput = JFactory::getApplication()->input;
    $keyword = $jinput->get('keyword', '', 'NULL');
    if($keyword!=''){
         $keyword = $db->Quote('%' . $db->escape($keyword, true) . '%');
            $query->where('( a.title LIKE '.$keyword.'  OR  a.features LIKE '.$keyword.'  OR  a.brand LIKE '.$keyword.' )');
    }

Cependant, les résultats de recherche sont très médiocres. Par exemple, la chaîne de recherche Google Nexus 5 correspond, alors que Google 5 Nexus ne fait pas. Quelle est la bonne façon de convertir cette requête en recherche de texte intégral dans Joomla 3.3

3
user2097091

NB. ce n'est pas un code testé qui vient juste d'être entré dans le navigateur, donc attention à ce que]

La première étape consisterait à vérifier le terme de recherche d'espaces, puis à explode() dans un array() contenant chacune des chaînes délimitées par des espaces. par exemple.

$keywordArray = explode(" ", $keyword);

Si vous voulez seulement ​​trouver du contenu contenant tous les mots-clés, vous devez également utiliser un AND plutôt qu'un OR . En passant, l’appel $db->quote() que vous avez effectue automatiquement un escape() de la façon dont vous l’utilisez (je ne suis pas sûr s'il détecte le texte précédemment échappé avec le caractère d'échappement supplémentaire ou pas dans votre cas).

Donc, pour construire votre where, vous pouvez parcourir le tableau avec quelque chose comme:

if($keyword!=''){
    $keywordArray = explode(" ", $keyword);

    foreach ($keywordArray as $keyword)
    {
        $searchTerm = $db->Quote('%' . $keyword . '%');
        $query->where('( a.title LIKE '.$searchTerm.' AND a.title LIKE '.$searchTerm.' AND a.title LIKE '.$searchTerm.' )');
        $query->where('( a.features LIKE '.$searchTerm.' AND a.features LIKE '.$searchTerm.' AND a.features LIKE '.$searchTerm.' )');
        $query->where('( a.brand LIKE '.$searchTerm.' AND a.brand LIKE '.$searchTerm.' AND a.brand LIKE '.$searchTerm.' )');
    }
}

Cela dit, cela pourrait être une lourde charge pour MySQL, c'est une base de données relationnelle après tout pas un moteur de recherche. Vous voudrez peut-être faire des choses comme:

  1. Donner à l'utilisateur la possibilité de rechercher dans une seule de ces colonnes
  2. Limitez le nombre de mots en entrée, imaginez une recherche de 10 mots ou plus.
  3. Regardez les options comme MATCH et MATCH AGAINST
1
Craig

Je suis confronté au même problème, surtout lorsque vous avez de grands ensembles de données. J'ai aussi essayé les solutions MATCH et MATCH AGAINST, mais elles n'étaient pas vraiment utiles pour la recherche en texte intégral. À la fin, j’ai écrit mon propre plug-in Finder et migre mes extensions pour la recherche en texte intégral à utiliser recherche intelligente . Je ne sais pas si c'est une option pour vous.

1
Laoneo