2011-05-02 3 views
0

Mon Pname original dans la table «anglais» est «La tasse numérique de Santa Monica» .Si les utilisateurs essayent de rechercher en utilisant «la tasse numérique», son produit ne retournant pas le pname contenant la tasse numérique.Comment rechercher les mots aléatoires d'une phrase en utilisant PHP?

je utilise cette requête:

select * 
from english 
where((pname like '%$val%' 
     or desp1 like '%$search%' 
     or pid like '%$search%' $key_value) 
     and warehouse=0 and cid !=49) 
group by pid; 
+0

utilisateur - Pouvez-vous décrire mieux cela? Il semble que 'pname' est un champ de la table' english' mais qu'est-ce que c'est avec les variables PHP? '$ val',' $ search', '$ key_value' ?? –

+0

Ils sont la valeur des formes ... Merci j'ai implémenté la requête Gaurav et son fonctionnement. – user734024

Répondre

2

utilisation pname like '%".implode('%', explode(' ', $val))."%' au lieu de pname like '%$val%'

Dans cet ordre de cas d'importance. Moyens Digital Mug vous donnera le résultat, mais MUG Digital ne sera pas.

+0

Merci .. Son bon fonctionnement .. – user734024

+0

qu'en est-il ''% ". str_replace ('', '%', $ val). '%') '? ;) Je conseille aussi de remplacer '%' par '\%' et '_' par' \ _' dans '$ val' avant de le placer dans la requête. Et ne pas oublier les injections sql ... – binaryLV

+0

@binaryLV: merci. – Gaurav

1

Vous pouvez diviser la valeur d'entrée en deux mots différents. Pour faire cela, maintenant

$term_array = explode(" ", $val); 

, term_array de $ tiendra séparément les deux mots, et vous pouvez exécuter des requêtes sur les mots individuellement. Par exemple, vous pouvez parcourir deux fois la requête et exécuter la même requête sur les mots uniques. Cependant, cela entraînerait des doublons (et probablement des résultats inutiles). Vous pourriez probablement penser à une sorte de requête en utilisant les deux mots séparés qui donneraient de meilleurs résultats, cependant.

0

Pour construire requête:

$split = explode(" ", $val); 
$qry_pname = "pname LIKE '%".implode("%' or pname LIKE '%", $split)."'%"; 

$qry = " 
SELECT * 
    FROM english 
WHERE($qry_pname 
     or desp1 like '%$search%' 
     or pid like '%$search%' $key_value) 
     and warehouse=0 and cid !=49) 
group by pid; 
"; 
1

Utilisez les recherches de texte intégral pour que

La chose ne fonctionne pas comme The Digital Santa Monica Mug lorsqu'il est recherché comme Digital Mug sera considéré comme '%Digital Mug%' qui tente de faire correspondre une valeur ayant Digital Mug avoir des mots avant et après.

Eg : THE Digital Mug Paradise 

Un tel texte sera apparié.

Donc, essayez MYSQL recherche en texte intégral pour que

FULL TEXT SEARCH

1

Soit ce que le C Man conseillé (diviser la phrase de recherche et rechercher tous les mots), ou la recherche de texte intégral.


Pour la méthode "mots de division", je conseille de:

  • utiliser des expressions régulières pour le fractionnement, quelque chose comme
    preg_match_all('#[a-zA-Z0-9]+#', $text, $words);
    vous n'avez pas besoin de rechercher des symboles comme "$", et vous?
  • écrivez une fonction qui générerait la clause where pour vous.

Fonction pour générer where clause pourrait ressembler à ceci:

function generateFilter(array $fields, array $words) { 
    // prepare $word for putting into SQL statement 
    foreach ($words as &$word) { 
     // ensure that wildcard characters are used as regular characters 
     $word = str_replace('%', '\\%', $word); 
     $word = str_replace('_', '\\_', $word); 
     // prevent SQL injections 
     $word = mysql_real_escape_string($word); 
    } 
    unset($word); 
    // generate filter 
    $filter = array(); 
    foreach ($words as $word) { 
     $wordFilter = array(); 
     foreach ($fields as $field) { 
      $wordFilter[] = "{$field} like '%$word%'"; 
     } 
     $filter[] = implode(' or ', $wordFilter); 
    } 
    $filter = '(' . implode(') and (', $filter) . ')'; 
    return $filter; 
} 
$filter = generateFilter(
    array('name', 'surname', 'address'), 
    array('john', 'doe') 
); 
echo $filter; 

Résultat:

(name like '%john%' or surname like '%john%' or address like '%john%') and 
(name like '%doe%' or surname like '%doe%' or address like '%doe%') 

Si vous utilisez des instructions préparées (qui est fortement conseillé), cette fonction serait un peu plus compliqué, car la chaîne résultante aurait des espaces réservés pour les variables, tandis que $ mots seraient placés dans un tableau de variables qui doivent être liées à l'instruction préparée.


La méthode "Séparer les mots" fonctionne pour les petites chaînes et les petites quantités de données. Si vous avez d'énormes quantités de données et/ou de grandes chaînes, pensez à utiliser la recherche fulltext. Il n'a pas besoin de diviser la phrase de recherche, mais il a quelques limitations - il a besoin d'un index fulltext sur les colonnes utilisées pour la recherche (IIRC, vous pouvez créer un index sur plusieurs colonnes et utiliser la recherche fulltext sur toutes les colonnes indexées en même temps, c'est-à-dire que vous n'avez pas besoin de rechercher toutes les colonnes), il a une longueur minimale de mots-clés et peut donner des résultats non-stricts, par exemple, seulement 3 des 5 mots-clés peuvent apparaître dans le résultat. Cependant, il donne la pertinence de chaque résultat - les résultats qui sont plus proches des termes de recherche auront une plus grande pertinence. Ceci est utile pour trier les résultats par pertinence.

Bien que la création d'index puisse sembler être un «travail supplémentaire» pour vous, cela permettra au SGBD d'effectuer la recherche plus rapidement que sans index.

+0

Vous devez changer l'ordre de 'str_replace' et' mysql_real_escape_string'. Sinon, un '%' deviendra d'abord '\%' par 'str_replace' et ensuite' \\% 'par' mysql_real_escape_string'. – Gumbo

+0

@Gumbo, cela peut sembler être faux, même si cela fonctionne - testé à la fois PHP avec 'mysql_query()' et à partir du client console MySQL. Valeur dans DB - ''viens% divi'',' where' caluse - 'où str' '% viens \\% divi%''. – binaryLV

+0

@Gumbo, de http://dev.mysql.com/doc/refman/5.1/fr/string-comparison-functions.html - "* Parce que MySQL utilise la syntaxe d'échappement C dans les chaînes (par exemple," \ n "pour représente un caractère de retour à la ligne), vous devez doubler tout "\" que vous utilisez dans les chaînes LIKE Par exemple, pour rechercher "\ n", spécifiez-le comme "\\ n". Pour rechercher "\", spécifiez-le comme "\\\\"; ceci est dû au fait que les barres obliques inverses sont effacées une fois par l'analyseur et à nouveau lorsque la correspondance de modèle est faite, ce qui permet de faire correspondre une seule barre oblique inverse. * ". Donc, bien que ''\%'' fonctionne, il * devrait * être écrit comme '\\%' '. – binaryLV

Questions connexes