Поисковая система Ключевые слова Парсер - PullRequest
8 голосов
/ 29 июля 2011

Вот что я хочу сделать:

Мне нужно создать анализатор поисковой системы, который использует следующие операторы:

  • Яблоки И Апельсины (Оператор AND)
  • Яблоки ИЛИ Апельсины (оператор ИЛИ)
  • Яблоки И НЕ Апельсины (И оператор НЕ)
  • " Яблоки " (Оператор котировок)
  • Яблоки И ( Апельсины ИЛИ Груши ) (Оператор в скобках)
  • Appl * (оператор Star)

С некоторым preg_replace мне удается преобразовать строку в массив, а затем я проанализировал этот массив, чтобы получить запрос MySQL.Но мне это не нравится, и оно очень нестабильно!

Я искал в Интернете какой-то скрипт, который это делает, и мне не повезло!

Может кто-нибудь помочь мне реализоватьэто ??

спасибо

Ответы [ 5 ]

3 голосов
/ 01 августа 2011

Хорошо, это будет большой ответ.

Я думаю, что вам нужен генератор синтаксических анализаторов.Часть программного обеспечения, которая генерирует код для анализа текста в соответствии с заданной грамматикой.Эти парсеры часто имеют 2 основных компонента: лексер и парсер.Лексер определяет TOKENS (слова), анализатор проверяет правильность порядка токенов в соответствии с вашей грамматикой.

В лексере вы должны объявить следующие токены

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

Грамматика должнаопределяется следующим образом:

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

Эта грамматика определяет язык со всеми необходимыми вам функциями.В зависимости от программного обеспечения, которое вы используете, вы можете определить функции для обработки каждого правила.Таким образом, вы можете преобразовать свой текстовый запрос в предложение sql where.

Я не очень разбираюсь в php, но я искал в интернете генератор парсера и появился PHP_ParserGenerator .

Имейте в виду, что по мере роста вашей базы данныхзапросы могут стать проблемой для структурированной системы хранения.

Возможно, вы захотите попробовать механизм полнотекстового поиска, который позволяет вам выполнять эту и многие другие функции, связанные с текстовым поиском.Вот как IndexTank работает

Сначала вы добавляете (или 'index' на поисковом диалекте) все свои записи базы данных (или документы) в IndexTank.

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

После этого вы можете выполнять поиск по индексу по всем нужным операторам

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

Надеюсь, я ответил на ваш вопрос.

1 голос
/ 29 июля 2011

Кроме того, это не совсем то, что вы ищете, но, возможно, близко: Полнотекстовый поиск MySQL .

0 голосов
/ 29 июля 2011

Попробуйте: http://www.isearchthenet.com/isearch/index.php

Из файла readme:

  • Поиск обычно выполняется со словами "может содержать".Для соответствия требуется, чтобы любое из введенных слов присутствовало на странице.
  • Вы можете искать страницы, содержащие определенное слово, добавив к нему знак плюс (+).Будут показаны только страницы, содержащие это слово.
  • Вы можете игнорировать все страницы, содержащие определенное слово, добавив к нему знак минус (-).Любая страница, содержащая это слово, не будет отображаться в результатах поиска.
  • Вы можете искать конкретную фразу, заключив ее в двойные кавычки ("). Будут показаны только страницы, содержащие эту точную фразу.

Его легко установить и использовать. Также обратите внимание на http://sphinxsearch.com/ - самый мощный двигатель, но не для новичков.

0 голосов
/ 29 июля 2011

Вы можете создать что-то вроде следующего ( ВАЖНО: $search строка должна быть сначала санирована, или вас взломают) ...

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);
}
0 голосов
/ 29 июля 2011

вы смотрели на ANTLR

...