MySQL Whole Word Match - несколько слов - PullRequest
0 голосов
/ 23 февраля 2019

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

Один из вариантов поиска в моем терминологическомсловарь "только целые слова".Сначала я использовал

WHERE ".$source." RLIKE '[[:<:]]".$keyword."[[:>:]]'

Однако это не соответствовало целым словам для первого или второго $keyword, когда их больше одного.Затем я нашел

WHERE ".$source." REGEXP '[[:<:]]".$keyword."[[:>:]]'

и

WHERE ".$source." REGEXP '(^| )".$keyword."( |$)'

при поиске этих форумов

Я только что проверил оба из вышеперечисленных в своем PhpMyAdmin и нашелиз-за того, что первый выполняется за 0,0740 секунд, а второй - вдвое дольше, 0,1440 секунд, так что, думаю, мне следует придерживаться первого.

Больше всего меня беспокоит огромное расхождение в результатах, например, поискдля одного слова («инструмент»):

  1. Использование границы слов [[:<:]] и [[:>:]] в PhpMyAdmin возвращает 34 результата.

  2. Использование (^| ) и ( |$) в PhpMyAdmin возвращает 26 результатов.

  3. Выполнение регулярного выражения # 1 в моем PHP-скрипте возвращает 34 результата (это правильное число).

Вот весь блок MySQL:

foreach($keywords as $keyword) {
    $query = $db->query("SELECT * FROM ".DICTIONARY_TABLE." " .
    "JOIN ".DICTIONARY_THEMES." ON ".DICTIONARY_TABLE.".theme_id = ".DICTIONARY_THEMES.".theme_id ".
    "LEFT JOIN ".DICTIONARY_DEFINITIONS." ON ".DICTIONARY_TABLE.".term_id = ".DICTIONARY_DEFINITIONS.".term_id ".
    "WHERE ".DICTIONARY_TABLE.".".$source." REGEXP '(^| )".$keyword."( |$)'".
    //"WHERE ".DICTIONARY_TABLE.".".$source." REGEXP '[[:<:]]".$keyword."[[:>:]]'".
    " ORDER BY ".DICTIONARY_TABLE.".theme_id, ".DICTIONARY_TABLE.".".$source."");
}

Я прокомментировал опцию поиска, которую я не использую.

Теперь, если я попробую ДВАключевые слова, например, «режущий инструмент», я все еще получаю 34 результатов на странице.Я не уверен, что я делаю это правильно в PhpMyAdmin:

SELECT * FROM `asphodel_dictionary_terms` WHERE english REGEXP '[[:<:]]cutting[[:>:]]';
SELECT * FROM `asphodel_dictionary_terms` WHERE english REGEXP '[[:<:]]tool[[:>:]]'

Это возвращает 44 результата для "резки" и 34 результата для "инструмента".Запрос с использованием (^| ) ... возвращает 37 + 26 результатов соответственно.

Любая обратная связь, которая поможет мне разобраться, будет принята с благодарностью!

База данных содержит в общей сложности 109 000 записей вВ основной таблице 82 таблицы в таблице DICTIONARY_THEMES и 727 записей в таблице DICTIONARY_DEFINITIONS.Не огромная база данных, и она не станет намного больше.

1 Ответ

0 голосов
/ 23 февраля 2019

Вы получаете разные результаты, потому что два регулярных выражения не идентичны.

(^| ) означает: либо начало строки, либо пробел (( |$) имеет одинаковое значение в конце строки).

[[:<:]] и [[:>:]] являются границами слов : концептуально это относится к символам, которые разделяют слова, и, как правило, механизмы регулярных выражений интерпретируют его как что-то вроде: что угодно, кроме цифры, буквы илисимвол подчеркивания.

Таким образом, первый шаблон является более строгим, чем второй (пробел, начало и конец строки являются границами слов, но есть и другие).

Если у вас есть более одного ключевого слова для поиска, вам нужно будет повторить совпадения с регулярным выражением, например:

WHERE 
    ".$source." RLIKE '[[:<:]]".$keyword1."[[:>:]]'
    OR ".$source." RLIKE '[[:<:]]".$keyword2."[[:>:]]'

или создать новое регулярное выражение, комбинируя ключевые слова:

WHERE 
    ".$source." RLIKE '[[:<:]](".$keyword1.")|(".$keyword2.")[[:>:]]'

NB: для требования поиска вам следует рассмотреть возможность использования полнотекстового поиска MySQL , который в первую очередь предназначен для поиска полных слов (хотя есть предварительные условия).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...