2011-07-29 3 views
8

Voici ce que je veux faire:Moteur de recherche Mots-clés Parser

Je dois créer un analyseur de moteur de recherche qui utilise les opérateurs suivants:

  • pommes ET Oranges (opérateur AND)
  • pommes OU oranges (opérateur OR)
  • pommes ET NON oranges (opérateur AND NOT)
  • " pommes " (opérateur Citations)
  • Pommes ET ( Oranges OU poires ) (opérateur Parenthèses)
  • Appl * (opérateur étoiles)

Avec Certains preg_replace, je parviens à convertir la chaîne dans un tableau, puis j'ai analysé ce tableau pour obtenir une requête MySQL. Mais je n'aime pas ça et c'est très instable!

J'ai cherché sur le web un script qui fait ça et je n'ai pas eu de chance! Est-ce que quelqu'un peut m'aider s'il vous plaît à mettre en œuvre ce ??

Merci

+0

Normalement, vous devez d'abord marquer l'entrée, puis exécuter un analyseur sur les données à jetons. Mon [convertisseur print_r] (https://gist.github.com/1102761) fait quelque chose de similaire, cependant, il a une grammaire différente. – hakre

Répondre

0

Avez-vous regardé ANTLR

+1

+1, merci pour le lien. – hakre

-1

Essayez ceci: http://www.isearchthenet.com/isearch/index.php

De readme:

  • recherches sont normalement effectuées avec " peut contenir " mots. Une correspondance nécessite que l'un des mots saisis soit présent sur la page.
  • Vous pouvez rechercher des pages contenant un mot spécifique en le préfixant avec un signe plus (+). Seules les pages contenant ce mot seront affichées.
  • Vous pouvez ignorer toutes les pages contenant un mot spécifique en le préfixant avec un signe moins (-). Toute page contenant ce mot ne sera pas affichée dans les résultats de la recherche.
  • Vous pouvez rechercher une expression spécifique en l'encadrant entre guillemets ("). Seules les pages contenant cette phrase exacte seront affichées.

Facile à installer et à utiliser. Jetez aussi un oeil à http://sphinxsearch.com/ - le moteur le plus puissant, mais pas pour les débutants.

0

Vous pouvez homebrew quelque chose comme ce qui suit (IMPORTANT:$search chaîne doit d'abord être aseptisé ou vous être piraté) ...

if (substr($search[0]=='*' and substr($search,-1)=='*') { 
    // *ppl* 
    $query = "SELECT * FROM `table` WHERE `field` LIKE (%'". str_replace('*','',$search) ."%')"; 
} elseif (substr($search,-1)=='*') { 
    // Appl* 
    $query = "SELECT * FROM `table` WHERE `field` LIKE ('". str_replace('*','',$search) ."%')"; 
} elseif ($search[0]=='*') { 
    // *Appl 
    $query = "SELECT * FROM `table` WHERE `field` LIKE ('%". str_replace('*','',$search) ."')"; 
} elseif (substr_count($search,'"')==2) { 
    // " Apples " ... just remove the " 
    $query = 'SELECT * FROM `table` WHERE `field` = "'. str_replace('"','',$search) .'"'; 
} elseif (strpos($search,')') or strpos($search,'(')) { 
    // uh ... something more complex here 
    $query = '#idunno'; 
} else { 
    // the rest 
    $query = 'SELECT * FROM `table` WHERE `field` = "'. $search .'"'; 
    $search = array(
     ' AND ', 
     ' OR ', 
     ' AND NOT ' 
     ); 
    $replace = array(
     '" AND `field` = "', 
     '" OR `field` = "', 
     '" AND `field != "' 
     ); 
    str_replace($search,$replace,$query); 
} 
1

En outre, ce n'est pas exactement ce que vous cherchez, mais peut-être près: MySQL en texte intégral recherche.

+1

La recherche de texte intégrée de MySQL est agréable, pour la recherche de base de texte en langage naturel. Mais si vous souhaitez interroger d'autres types de texte, autoriser des options avancées ou rechercher des mots de moins de quatre lettres, vous devez généralement être plus créatif. – Steven

+0

['IN BOOLEAN MODE'] (http://dev.mysql.com/doc/refman/5.5/fr/fulltext-boolean.html) fait presque exactement ce que l'OP demande, et le réglage de la longueur de mot minimum est inférieur à assez facile. Ce serait un remplacement assez simple des opérateurs. +1 à cela. – Wrikken

3

Ok, cela va être une grande réponse.

Je pense que vous avez besoin d'un générateur d'analyseur. Un logiciel qui génère du code pour analyser le texte en fonction d'une grammaire donnée. Ces analyseurs ont souvent 2 composants principaux: un lexeur et un analyseur. Le lexer identifie TOKENS (mots), l'analyseur vérifie si l'ordre du jeton est correct selon votre grammaire.

Dans le lexer, vous devez déclarer les jetons suivants

TOKENS ::= (AND, OR, NOT, WORD, WORDSTAR, LPAREN, RPAREN, QUOTE) 
WORD ::= '/w+/' 
WORDSTAR ::= '/w+\*/' 

La grammaire doit être définie comme ceci:

QUERY ::= word 
QUERY ::= wordstar 
QUERY ::= lparen QUERY rparen 
QUERY ::= QUERY and QUERY 
QUERY ::= QUERY or QUERY 
QUERY ::= QUERY and not QUERY 
QUERY ::= quote MQUERY quote 
MQUERY ::= word MQUERY 
MQUERY ::= word 

Cette grammaire définit une langue avec toutes les fonctionnalités de votre besoin. Selon le logiciel que vous utilisez, vous pouvez définir des fonctions pour gérer chaque règle. De cette façon, vous pouvez transformer votre requête textuelle en une clause sql where.

Je ne suis pas vraiment en PHP, mais j'ai cherché sur le web pour un générateur d'analyseur et PHP_ParserGenerator est apparu. Gardez à l'esprit que tant que votre base de données se développe, ces requêtes peuvent devenir un problème pour un système de stockage structuré.

Vous voudrez peut-être essayer un moteur de recherche de texte intégral qui vous permet d'effectuer ceci et beaucoup d'autres dispositifs liés à la recherche de texte. C'est ainsi que fonctionne IndexTank

D'abord, vous ajoutez (ou 'indexez' dans le dialecte de recherche) tous vos enregistrements de db (ou documents) à IndexTank.

$api = new ApiClient(...); 
$index = $api->get_index('my_index'); 
foreach ($dbRows as $row) { 
    $index->add_document($row->id, array('text' => $row->text)); 
} 

Après cela, vous pouvez effectuer une recherche dans l'index avec tous les opérateurs que vous voulez

$index = $api->get_index('my_index'); 
$search_result = $index->search('Apples AND Oranges'); 
$search_result = $index->search('Apples OR Oranges'); 
$search_result = $index->search('Apples AND NOT Oranges'); 
$search_result = $index->search('"apples oranges"'); 
$search_result = $index->search('Apples AND (Oranges OR Pears)'); 
$search_result = $index->search('Appl*'); 

J'espère avoir répondu à votre question.