2011-07-29 21 views
8

Oto, co chcę zrobić:Wyszukiwarka Słowa kluczowe Parser

trzeba utworzyć parser wyszukiwarki, który używa następujących operatorów:

  • Jabłka I Pomarańcze (i operator)
  • Jabłka OR Pomarańcze (lub operator)
  • Jabłka i nie Pomarańcze (a nie operator)
  • " Jabłka " (operator cudzysłowów)
  • Jabłka I ( Pomarańcze LUB Gruszki ) (operator nawiasów)
  • Appl * (operator Gwiazda)

Z niektóre preg_replace, udało mi się przekonwertować ciąg znaków do tablicy, a następnie przeanalizowałem tę tablicę, aby uzyskać zapytanie MySQL. Ale nie podoba mi się ta droga i jest bardzo niestabilna!

Przeszukałem internet pod kątem skryptu, który to robi i nie miałem szczęścia!

Czy ktoś może mi pomóc w realizacji tego?

Dzięki

+0

Zwykle najpierw tokenizujesz dane wejściowe, a następnie uruchamiasz analizator składni na tokenizowanych danych. Mój [konwerter print_r] (https://gist.github.com/1102761) robi coś podobnego, jednak ma inną gramatykę. – hakre

Odpowiedz

-1

Spróbuj tego: http://www.isearchthenet.com/isearch/index.php

Od readme:

  • Wyszukiwania są zwykle wykonywane z " może zawierać " słowa. Dopasowanie wymaga wpisania dowolnego słowa na stronie.
  • Możesz wyszukiwać strony zawierające określone słowo, poprzedzając je znakiem plus (+). Wyświetlą się tylko te strony, które zawierają to słowo.
  • Możesz zignorować wszystkie strony zawierające określone słowo, poprzedzając je znakiem minus (-). Każda strona zawierająca to słowo nie będzie wyświetlana w wynikach wyszukiwania.
  • Możesz wyszukać określoną frazę, ujmując ją w cudzysłów ("). Wyświetlą się tylko te strony, które zawierają dokładnie tę frazę.

Jest łatwy w instalacji i użyciu. Zobacz także http://sphinxsearch.com/ - najmocniejszy silnik, ale nie dla początkujących.

0

Możesz homebrew coś podobnego (WAŻNE:$search ciąg musi być najpierw oczyszczone lub hacked) ...

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

Ponadto, nie jest to dokładnie to, czego szukasz, ale może blisko: MySQL pełnotekstowego przeszukiwania.

+1

Wbudowane wyszukiwanie tekstu MySQL jest dobre, do podstawowego wyszukiwania tekstu w języku naturalnym. Ale jeśli chcesz zapytać o inne rodzaje tekstu, zezwolić na zaawansowane opcje lub wyszukiwać słowa krótsze niż cztery litery, zazwyczaj musisz uzyskać więcej kreatywności. – Steven

+0

['IN BOOLEAN MODE'] (http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html) robi prawie dokładnie to, o co prosi OP, a ustawienie minimalnej długości słowa jest niższe raczej latwo. Byłaby to dość prosta wymiana operatorów. +1 do tego. – Wrikken

3

Ok, to będzie duża odpowiedź.

Myślę, że potrzebny jest generator parsera. Fragment oprogramowania generującego kod do parsowania tekstu zgodnie z gramatyką. Te parsery często mają 2 główne komponenty: lexer i parser. Lexer identyfikuje TOKENS (słowa), parser sprawdza czy kolejność tokenów jest zgodna z twoją gramatyką.

W lexer, należy zadeklarować następujące znaki

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

Gramatyka powinny być zdefiniowane tak:

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 

Ta gramatyka definiuje język ze wszystkich funkcji potrzeb. W zależności od używanego oprogramowania można zdefiniować funkcje do obsługi każdej reguły. W ten sposób możesz przekształcić zapytanie tekstowe w klauzulę where gdzie.

Nie jestem naprawdę w php, ale przeszukałem sieć dla generatora analizatora składni i pojawił się PHP_ParserGenerator.

Należy pamiętać, że tak długo, jak baza danych rośnie, zapytania te mogą stać się problemem dla strukturalnego systemu pamięci masowej.

Możesz chcieć wypróbować pełnotekstową wyszukiwarkę, która pozwoli ci wykonać tę i wiele innych funkcji związanych z wyszukiwaniem tekstu. W ten sposób najpierw dodajesz (lub "indeksujesz" w dialekcie wyszukiwania) wszystkie swoje rekordy db (lub dokumenty) do IndexTank.

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

Po tym, można szukać w indeksie ze wszystkimi operatorami chcesz

$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*'); 

Mam nadzieję, że odpowiedział na to pytanie.

Powiązane problemy