2009-01-02 7 views
8

Je travaille sur une page 'recherche avancée' sur un site où vous entrez un mot-clé tel que 'J'aime les pommes' et il peut chercher dans la base de données en utilisant les options suivantes:'Recherche Avancée' Page

Recherche: Avec tous les mots, Avec l'expression exacte , avec au moins l'un des les mots, sans les mots

Je peux prendre soin de la « phrase exacte » par:

SELECT * FROM myTable WHERE field='$keyword'; 

« au moins un des mots » par:

SELECT * FROM myTable WHERE field LIKE '%$keyword%';//Let me know if this is the wrong approach 

Mais son du « Avec au moins un des mots » et « Sans les mots » que je suis coincé sur.

Des suggestions sur la façon de mettre en œuvre ces deux?

Edit: En ce qui concerne 'Au moins un mot, il ne serait pas une bonne approche pour utiliser explode() pour casser les mots-clés en mots, et exécuter une boucle pour ajouter

(field='$keywords') OR ($field='$keywords) (OR).... 

Parce qu'il Il y a aussi d'autres clauses AND/OR dans la requête et je ne connais pas le nombre maximum de clauses possibles.

Répondre

12

Je suggère l'utilisation de MySQL FullText Search en utilisant cela avec la fonctionnalité Boolean Full-Text Searches vous devriez être en mesure d'obtenir le résultat souhaité.

Edit:

exemple demandé en fonction de vos conditions demandées ("Son seul champ et ils peuvent choisir l'une des 4 options (i.e. 1 mot, mots exacts, au moins 1 mot, sans le terme).«)

Je suppose que vous utilisez PHP en fonction de votre message initial

<?php 
$choice = $_POST['choice']; 
$query = $_POST['query']; 

if ($choice == "oneWord") { 
    //Not 100% sure what you mean by one word but this is the simplest form 
    //This assumes $query = a single word 
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('{$query}' IN BOOLEAN MODE)"); 
} elseif ($choice == "exactWords") { 
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('\"{$query}\"' IN BOOLEAN MODE)"); 
} elseif ($choice == "atLeastOneWord") { 
    //The default with no operators if given multiple words will return rows that contains at least one of the words 
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('{$query}' IN BOOLEAN MODE)"); 
} elseif ($choice == "withoutTheTerm") { 
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('-{$query}' IN BOOLEAN MODE)"); 
} 
?> 

espérons que cette aide pour une utilisation complète des opérateurs dans des matchs booléennes voir Boolean Full-Text Searches

+0

+1, c'est la meilleure réponse, mais je voudrais aussi détails que fulltext sur mysql n'est disponible que pour les tables myisam, pas innodb, donc vous choisissez entre la cohérence transactionnelle ou la recherche –

+0

Si vous donnez du code source qui montre comment les deux caractéristiques (ie tous les mots et sans les mots) peuvent être faites avec le texte intégral, je pourrais accepter votre réponse –

+0

Je serais heureux de vous fournir un exemple de code.Si vous pouvez me dire s'il y a deux champs séparés dans votre formulaire de recherche pour avec ou sans ou utilisez-vous un champ? Si c'est un champ vous pouvez simplement permettre à l'utilisateur d'ajouter les mots qu'il veut exclure avec un - –

2

Vous pouvez utiliser

Avec au moins un des mots

SELECT * FROM myTable WHERE field LIKE '%$keyword%' 
or field LIKE '%$keyword2%' 
or field LIKE '%$keyword3%'; 

Sans le mot

SELECT * FROM myTable WHERE field NOT LIKE '%$keyword%'; 
+0

S'il vous plaît voir mon edit ci-dessus. Pensez-vous que c'est une bonne solution, par exemple, y a-t-il une limite au nombre de clauses OR qui peuvent être placées dans une requête? –

+0

Il y a probablement une limite, mais je ne l'ai jamais atteinte et j'ai fait beaucoup plus de temps pour les instructions, mais plus vous ajoutez de temps, plus la requête sera lente et "like" particulièrement lente. – Re0sless

+0

Il n'y a pas de limite pratique. Si vous avez d'autres clauses WHERE, mettez entre parenthèses votre recherche par mot-clé: "WHERE quelque chose = x ET (champ LIKE ... OU champ LIKE ... OU ...) – Greg

2

Je ne suis pas sûr que vous pouvez facilement faire ces options de recherche dans une naïve manière comme les deux autres.

Il serait utile de mettre en place un meilleur moteur de recherche si vous avez besoin de prendre en charge ces scénarios. Un simple qui pourrait probablement vous aider est quelque chose le long de ces lignes:

Lorsqu'un élément est ajouté à la base de données, il est divisé en mots individuels. A ce stade, les mots "communs" (the, a, etc ...) sont supprimés (probablement basés sur une table common_words). Les mots restants sont ajoutés à une table de mots s'ils ne sont pas déjà présents. Il y a alors un lien entre l'entrée de mot et l'entrée d'article.

Lors de la recherche, il est alors possible d'obtenir le mot ids à partir de la table de mots et la recherche appropriée des identifiants d'éléments dans la table de jointure.

1

Search est notoirement difficile à faire bien .

Vous devriez envisager d'utiliser un moteur de recherche tiers en utilisant quelque chose comme Lucene ou Sphider.

0

Giraffe et Re0sless pooseted 2 bonnes réponses.

notes: "SELECT *" suce ... sélectionnez uniquement les colonnes dont vous avez besoin. Re0sless met un "OU" entre les mots-clés. - vous devriez éliminer les mots communs ("", "i", "am", "et" .. etc) - mysql a une limite de 8kb je crois sur la taille de la requête, donc pour des SELECTS vraiment longs, vous devriez slipt dans des requêtes séparées. - essayer d'éliminer les mots clés en double (si je recherche "vous savez que vous aimez" le SELECT devrait fondamentalement seulement rechercher "vous" une fois et éliminez les mots communs comme "it")

Essayez également d'utiliser "LIKE" et "MATCH LIKE" (voir page de manuel mysql) il pourrait faire des merveilles pour les recherches "floues"

Questions connexes