web-dev-qa-db-fra.com

Comment implémenter une recherche par mot-clé dans MySQL?

Je suis nouveau dans la programmation SQL.

J'ai un travail de table où les champs sont id, position, category, location, salary range, description, refno.

Je veux implémenter un recherche par mot-clé à partir du frontal. Le mot clé peut résider dans l'un des champs du tableau ci-dessus.

C'est la requête que j'ai essayée mais elle se compose de tant de lignes en double:

SELECT
    a.*,
    b.catname
FROM
    job a,
    category b
WHERE
    a.catid = b.catid AND
    a.jobsalrange = '15001-20000' AND
    a.jobloc = 'Berkshire' AND
    a.jobpos LIKE '%sales%' OR
    a.jobloc LIKE '%sales%' OR
    a.jobsal LIKE '%sales%' OR
    a.jobref LIKE '%sales%' OR
    a.jobemail LIKE '%sales%' OR
    a.jobsalrange LIKE '%sales%' OR
    b.catname LIKE '%sales%'
34
santanu

Pour un seul mot-clé dans les champs VARCHAR, vous pouvez utiliser LIKE :

SELECT id, category, location
FROM table
WHERE
(
    category LIKE '%keyword%'
    OR location LIKE '%keyword%'
)

Pour une description, il est généralement préférable d'ajouter un index de texte intégral et d'effectuer une recherche en texte intégral (MyISAM uniquement):

SELECT id, description
FROM table
WHERE MATCH (description) AGAINST('keyword1 keyword2')
53
Greg
SELECT 
    *
FROM 
    yourtable
WHERE 
    id LIKE '%keyword%' 
    OR position LIKE '%keyword%'
    OR category LIKE '%keyword%'
    OR location LIKE '%keyword%'
    OR description LIKE '%keyword%'
    OR refno LIKE '%keyword%';
7
Jon Bright

Idéalement, ayez une table de mots-clés contenant les champs:

Keyword
Id
Count (possibly)

avec un index sur Keyword. Créez un déclencheur d'insertion/mise à jour/suppression sur l'autre table afin que, lorsqu'une ligne est modifiée, chaque mot clé soit extrait et placé (ou remplacé) dans cette table.

Vous aurez également besoin d'un tableau de mots pour ne pas compter comme mots clés (si, et, alors, mais, ...).

De cette façon, vous obtiendrez la meilleure vitesse pour les requêtes voulant rechercher les mots-clés et vous pouvez implémenter (relativement facilement) des requêtes plus complexes telles que "contient Java et RCA1802".

"LIKE" les requêtes fonctionneront mais elles ne seront pas aussi évolutives.

6
paxdiablo

Vous pouvez trouver une autre option plus simple dans un fil ici: Match Against .. avec une aide plus détaillée dans 11.9.2. Recherches booléennes de texte intégral

C'est juste au cas où quelqu'un aurait besoin d'une option plus compacte. Cela nécessitera de créer un index FULLTEXT dans la table, ce qui peut être accompli facilement.

Informations sur la façon de créer des index (MySQL): MySQL FULLTEXT Indexing and Searching

Dans l'index FULLTEXT, vous pouvez avoir plusieurs colonnes répertoriées, le résultat serait une instruction SQL avec un index nommé search:

SELECT *,MATCH (`column`) AGAINST('+keyword1* +keyword2* +keyword3*') as relevance  FROM `documents`USE INDEX(search) WHERE MATCH (`column`) AGAINST('+keyword1* +keyword2* +keyword3*' IN BOOLEAN MODE) ORDER BY relevance;

J'ai essayé avec plusieurs colonnes, sans succès. Même si plusieurs colonnes sont autorisées dans les index, vous avez toujours besoin d'un index pour chaque colonne à utiliser avec l'instruction Match/Against.

Selon vos critères, vous pouvez utiliser les deux options.

5
raphie

Personnellement, je n'utiliserais pas la comparaison de chaînes LIKE sur le champ ID ou tout autre champ numérique. Il n'est pas logique de rechercher l'ID # "216"pour revenir 1621621651, 3216087, 5321668 ... et ainsi de suite et ainsi de suite; de même avec le salaire.

De plus, si vous souhaitez utiliser des instructions préparées pour empêcher les injections SQL, vous devez utiliser une chaîne de requête comme:

SELECT * FROM job WHERE `position` LIKE CONCAT('%', ? ,'%') OR ...
5
Calvin

Je vais vous expliquer la méthode que je préfère généralement:

Tout d'abord, vous devez tenir compte du fait que pour cette méthode, vous sacrifiez la mémoire dans le but de gagner en vitesse de calcul. Deuxièmement, vous devez avoir le droit de modifier la structure du tableau.

1) Ajoutez un champ (je l'appelle généralement "résumé") où vous stockez toutes les données de la table.

Le champ ressemblera à:

"n-n1-n2-n3-n4-n5-n6-n7-n8-n9" etc. où n est un seul mot

J'y parviens en utilisant une expression régulière qui remplace "" par "-". Ce champ est le résultat de toutes les données de table "digérées" dans une chaîne sigle.

2) Utilisez l'instruction LIKE% keyword% dans le champ de résumé:

SELECT * FROM table WHERE digest LIKE %keyword%

vous pouvez même créer une qUery avec une petite boucle afin que vous puissiez rechercher plusieurs mots-clés en même temps comme:

SELECT * FROM table WHERE 
 digest LIKE %keyword1% AND 
 digest LIKE %keyword2% AND 
 digest LIKE %keyword3% ... 
4
Francesco Panina