2011-04-01 3 views
2

Je suis nouveau à "chercher" dans MySQL et j'ai quelques tâches, dont je ne sais pas comment les atteindre de la meilleure façon.Fulltext Recherche dans MySQL

J'ai la table MySQL suivante dans ma base de données.

delimiter $$ 

CREATE TABLE `authors` (
    `id` int(11) NOT NULL, 
    `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL, 
    `count` int(11) NOT NULL DEFAULT '1', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name_UNIQUE` (`name`), 
    FULLTEXT KEY `name_fulltext` (`name`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci$$ 

La tâche est la suivante: Dans une forme html, je veux entrer un nom, disons "John Doe". Ce nom doit être recherché dans cette table, dans la colonne "nom". Je veux la requête pour retourner tous les noms similaires comme "John Due" ou "John Doé" et ainsi de suite. Ainsi, l'utilisateur peut choisir dans une liste le bon nom. Parfois, les gens veulent rechercher un nom comme "John van Doe" (style néerlandais). Cela devrait être affiché aussi dans la liste.

Comment cela est-il le mieux réalisé? Ou devrais-je mieux demander. Est-ce possible? =) J'utilise d'ailleurs un script cgi python, donc tous les modules que python peut contribuer sont disponibles.

Une autre question est: Comment puis-je rechercher juste "John" ou "Dow"? Chaque nom qui a "John" doit être affiché. J'ai essayé "O WH nom comme" John "" mais c'est trop lent. Y at-il un moyen plus rapide?

Nous vous remercions de vos suggestions.

+0

Personnellement, je pense que vous devriez vous pencher un peu sur la normalisation de la base de données. –

Répondre

1

La tâche est: Dans un formulaire html Je veux entrer un nom, disons "John Doe". Ce nom doit être recherché dans cette table, dans la colonne "nom". Je veux la requête pour retourner tous les noms similaires comme "John Due" ou "John Doé" et ainsi de suite. Ainsi, l'utilisateur peut choisir dans une liste le bon nom. Parfois, les gens veulent rechercher un nom comme "John van Doe" (style néerlandais). Cela devrait être affiché aussi dans la liste.

MySQL ne supporte pas les dictionnaires de synonymes, vous devriez donc fournir l'un vous-même.

Yahoo API fournit un service de correction orthographique que vous pouvez utiliser en soumettant une requête similaire à ceci:

SELECT * 
FROM search.spelling 
WHERE query='juhn doe' 

utilisant ce URL:

http://query.yahooapis.com/v1/public/yql?q=SELECT%20%20*%20%20FROM%20search.spelling%20WHERE%20query%20%3D%20'juhn%20doe'&format=json&diagnostics=true&callback=cbfunc 

Dès que vous recevez une liste de synonymes, vous pouvez les rechercher en utilisant cette requête à MySQL:

SELECT * 
FROM authors 
WHERE MATCH(name) AGAINST ('(+juhn +doe) (+john +doe)' IN BOOLEAN MODE) 

John Doé sera retourné par ceci puisque vous employez UTF8_GENERAL_CI qui est insensible à la casse et à l'accent.

Si vous voulez regarder juste pour John, utilisez cette requête:

SELECT * 
FROM authors 
WHERE MATCH(name) AGAINST ('+john' IN BOOLEAN MODE) 

Aussi, assurez-vous que vous avez paramètre ft_min_word_len réglé à une valeur raisonnable (1 est le meilleur) à my.cnf.

La valeur par défaut est 4, ce qui signifie qu'aucun nom de famille à trois lettres (comme Doe) ne sera indexé.

+0

Merci beaucoup! La dernière partie de votre réponse m'a beaucoup aidé! – Aufwind

0

Une façon de résoudre le problème serait de créer un canonical form pour les noms. Le nom canonique serait le même pour tous les noms similaires. Ensuite, quand vous voulez trouver John Doe ou John Doé ou quoi que ce soit, vous devez d'abord générer le nom canonique, puis faire la recherche par cela.

Bien sûr, la création d'un algorithme pour canoniser noms humains est très difficile, si vous voulez obtenir des choses comme Doe et En raison pour correspondre à l'autre. Une simple solution de base qui prendrait soin des autres cas que vous mentionnez serait de dépouiller tous les accents (à -> a) et enlever von, van etc.