Mysql
 sql >> Base de données >  >> RDS >> Mysql

Recherches en texte intégral dans MySQL :le bon, le mauvais et le truand

Parfois, lors d'une recherche dans une base de données MySQL, vous souhaiterez peut-être exécuter des requêtes de recherche en texte intégral sur des données basées sur des caractères. Aujourd'hui, nous discutons des avantages et des inconvénients de ces méthodes de recherche.

Que sont les recherches en texte intégral dans MySQL ?

La recherche en texte intégral est une technique qui vous permet de rechercher des enregistrements qui pourraient ne pas correspondre parfaitement aux critères de recherche. Les recherches en texte intégral dans MySQL sont effectuées lorsque certains index sont utilisés et ces index ont de nombreuses nuances uniques, notamment :

  • Pour que l'index soit considéré comme un index de texte intégral, l'index doit être de type FULLTEXT.
  • Les index FULLTEXT ne peuvent être utilisés que sur les tables exécutant les moteurs de stockage InnoDB ou MyISAM.
  • Les index FULLTEXT ne peuvent être créés que pour les colonnes CHAR, VARCHAR ou TEXT.
  • Les index FULLTEXT ne sont utilisés que lorsque la clause MATCH() AGAINST() est utilisée.
  • Les recherches en texte intégral ont trois modes :le mode langage naturel, le mode booléen et le mode d'extension de requête.

Un index FULLTEXT est un type spécial d'index qui trouve des mots clés dans le texte au lieu de comparer les valeurs aux valeurs de l'index. Bien que la recherche FULLTEXT soit différente des autres types de correspondance, notez que vous pouvez avoir un index BTREE et un index FULLTEXT sur la même colonne en même temps - ils ne seront pas en conflit car ils conviennent à des fins différentes.

Types de recherche en texte intégral

Lorsque vous exécutez des recherches en texte intégral dans MySQL, gardez à l'esprit qu'il existe trois types de recherche parmi lesquels choisir :

  1. Un type de recherche en langage naturel - un tel mode de recherche interprète la chaîne de recherche comme une phrase littérale. Activé par défaut si aucun modificateur n'est spécifié ou lorsque le modificateur IN NATURAL LANGUAGE MODE est spécifié ;
  2. Un type de recherche d'extension de requête - un tel mode de recherche effectue la recherche deux fois. Lors de la deuxième recherche, le jeu de résultats comprend quelques documents les plus pertinents de la première recherche. Activé à l'aide du modificateur WITH QUERY EXPANSION ;
  3. Un type de recherche booléen - un tel mode de recherche permet de rechercher des requêtes complexes pouvant inclure des opérateurs booléens tels que les opérateurs inférieur à ("<") et supérieur à (">"), les sous-expressions ("( " et ")"), le signe plus (+), le signe moins (-), les guillemets (""), un opérateur qui diminue la contribution de la valeur aux résultats (~) et l'opérateur générique (*) - le L'opérateur générique permet une recherche avec une correspondance approximative (par exemple, "demo*" correspondrait également à "demonstration"). Activé à l'aide du modificateur IN BOOLEAN MODE.

Recherches en texte intégral avec le mode de recherche en langage naturel

Un mode de recherche en langage naturel, comme indiqué ci-dessus, est activé par défaut ou lorsque le modificateur IN NATURAL LANGUAGE MODE est spécifié. Ce mode effectue une recherche en langage naturel sur une collection de texte donnée (une ou plusieurs colonnes). Le format de requête de base des recherches en texte intégral dans MySQL doit ressembler à ce qui suit :

SELECT * FROM table WHERE MATCH(column) AGAINST(“string” IN NATURAL LANGUAGE MODE);

Lorsque MATCH() est utilisé avec une clause WHERE, les lignes sont automatiquement triées en premier par la pertinence la plus élevée. Pour rechercher une chaîne exacte, placez-la entre guillemets doubles.

Recherches en texte intégral avec le mode d'extension de requête

Les recherches en texte intégral prennent également en charge le mode d'extension des requêtes. Un tel mode de recherche est fréquemment utilisé lorsque l'utilisateur s'appuie sur des connaissances implicites - par exemple, l'utilisateur peut rechercher "SGBD" en espérant voir à la fois "MongoDB" et "MySQL" dans les résultats de la recherche. La raison pour laquelle l'utilisateur peut s'appuyer sur certaines connaissances implicites lors de l'utilisation d'un tel mode de recherche est assez simple - une recherche de texte intégral avec le mode d'extension de requête fonctionne en effectuant la recherche deux fois :la deuxième expression de recherche est la première expression de recherche concaténé avec quelques entrées les plus pertinentes de la première recherche. Cela signifie que, par exemple, si dans la première recherche l'une des lignes contiendrait le mot "SGBD" et le mot "MySQL", la deuxième recherche trouverait les entrées qui contiendraient le mot "MySQL" même si elles ne le font pas. contiennent "SGBD". Le format de requête qui utiliserait le mode d'extension de requête ressemblerait à :

SELECT * FROM table WHERE MATCH(column) AGAINST(“string” WITH QUERY EXPANSION); 

Recherches en texte intégral à l'aide du mode booléen

Le mode booléen est peut-être l'une des choses les plus intéressantes que la recherche en texte intégral de MySQL a à offrir. Ce mode comporte de nombreuses mises en garde qui lui sont propres car il vous permet d'étendre les capacités de recherche à l'aide d'opérateurs booléens. Lorsque le mode booléen est utilisé, certains caractères peuvent avoir une signification particulière en début ou en fin de mots. Par exemple :

  • "+" signifie ET ;
  • "-" signifie NON ;
  • Les opérateurs "(" et ")" permettent de créer des sous-expressions ;
  • Les opérateurs "<" et ">" modifient le classement de la valeur de recherche vers le bas ou vers le haut ;
  • "~" réduit la contribution de la valeur aux résultats de recherche ;
  • Les guillemets ("") correspondent uniquement aux valeurs littérales ;
  • "*" est un opérateur générique (reportez-vous à l'explication ci-dessus).

Ces opérateurs vous permettent d'étendre la fonctionnalité de la recherche :par exemple, si vous souhaitez récupérer toutes les lignes contenant le mot "Demo", mais pas "Demo2", vous pouvez utiliser une requête comme ça :

SELECT * FROM table WHERE MATCH(column) AGAINST (“+Demo -Demo2” IN BOOLEAN MODE);

Vous pouvez également utiliser des guillemets doubles avec des guillemets simples comme ceci :

SELECT * FROM table WHERE MATCH(column) AGAINST(‘“search string”’ IN BOOLEAN MODE);

Les pièges de la recherche en texte intégral

Avant d'utiliser la recherche en texte intégral dans MySQL, gardez à l'esprit que la recherche comporte quelques "pièges" :

  • Les moteurs de stockage InnoDB et MyISAM ont leurs propres listes de mots vides. La liste des mots vides InnoDB peut être trouvée ici, la liste des mots vides MyISAM peut être trouvée ici.
    • Pour définir votre propre liste de mots vides pour InnoDB, définissez une table avec la même structure que la table INNODB_FT_DEFAULT_STOPWORD, insérez-y des mots vides, puis définissez la valeur de l'option innodb_ft_server_stopword_table sous la forme db_name/table_name.
    • Pour définir votre propre liste de mots vides pour MyISAM, définissez la variable ft_stopword_file sur le nom du chemin du fichier contenant la liste de mots vides. Dans le fichier, les mots vides peuvent être séparés par n'importe quel caractère non alphanumérique à l'exception de "_" et "'". Le fichier de mots vides par défaut se trouve dans storage/myisam/ft_static.c. Les mots vides peuvent être désactivés en définissant la variable sur une chaîne vide.
  • Les recherches en texte intégral ne sont pas prises en charge sur les tables partitionnées.
  • Toutes les colonnes d'un index FULLTEXT doivent utiliser le même jeu de caractères et le même classement.
  • Les opérations de recherche en texte intégral ne traitent pas la chaîne % comme un caractère générique.

Voici un autre hic :vous voudrez peut-être également garder à l'esprit que l'analyseur FULLTEXT intégré détermine où les mots commencent et se terminent en regardant certains caractères, y compris l'espace (" "), la virgule (", ”) et le point (“.””) signifiant que si votre chaîne de recherche contient un ou plusieurs de ces caractères, les résultats de la recherche pourraient ne pas être précis. Par exemple, si votre base de données contient 5 lignes avec la chaîne "test.demo", la requête de recherche "test.demo" peut renvoyer plus de résultats (10, 15, etc.), y compris "demo", "string.demo_example", etc. car il va rechercher "demo" au lieu de "test.demo", donc vous pourriez être coincé avec beaucoup de correspondances non pertinentes. MySQL propose une solution de contournement pour ce problème si vous êtes prêt à écrire votre propre plugin en C ou C++ (voir la documentation MySQL), mais jusque-là, vous ne pouvez pas faire grand-chose.

La liste complète des restrictions de texte intégral de MySQL peut être consultée sur la page de documentation de MySQL.

Résumé

La capacité de recherche en texte intégral MySQL offre un moyen simple d'implémenter diverses techniques de recherche (recherche en langage naturel, recherche d'extension de requête et recherche booléenne) dans votre application exécutant MySQL. Chacune de ces techniques de recherche a ses propres mises en garde et chacune d'entre elles peut être adaptée à des fins différentes - lorsque vous décidez d'utiliser ou non la recherche en texte intégral, gardez à l'esprit que ce type de recherche comporte de nombreuses subtilités qui lui sont propres, connaissez à la fois les avantages et inconvénients de l'utilisation de la recherche en texte intégral dans MySQL et choisissez judicieusement.