MySQL логического режима полнотекстового поиска с подстановочными знаками и литералами - PullRequest
6 голосов
/ 19 августа 2011

Я довольно новичок в полнотекстовом поиске MySQL и столкнулся с этой проблемой сегодня:

В таблице моей компании есть запись с "e-magazine AG" в столбце имени.У меня есть полнотекстовый индекс в столбце имени.

Когда я выполняю этот запрос, запись не найдена:

SELECT id, name FROM company WHERE MATCH(name) AGAINST('+"e-magazi"*' IN BOOLEAN MODE);

Мне нужно работать с кавычками из-за дефиса и доиспользуйте подстановочный знак, потому что я реализую функцию «поиск по мере ввода».

Когда я ищу весь термин «электронный журнал AG», запись обнаруживается.

Любые идеи о том, что яя здесь не так делаю?Я читал о добавлении тире в список символов слова (требуется обновление конфигурации), но я ищу способ сделать это программно.

Ответы [ 2 ]

3 голосов
/ 26 сентября 2011

Этот пункт

MATCH(name) AGAINST('+"e-magazi"*' IN BOOLEAN MODE);

Будет искать AND "e" AND NOT "magazi";то есть - внутри "e-magazi" будет интерпретироваться как not, даже если он находится внутри кавычек.
По этой причине он не будет работать должным образом.having предложение с как.

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

Я предлагаю что-то вроде:

SELECT id, name 
FROM company 
WHERE MATCH(name) AGAINST('magazine' IN BOOLEAN MODE)
HAVING name LIKE '%e-magazi%';
1 голос
/ 29 января 2017

Полный текст MySQL обрабатывает слово e-magazine в тексте как фразу и , а не как слово. Из-за этого это приводит к двум словам e и magazine. И хотя он строит поисковый индекс, он не добавляет e к индексу из-за ft_min_word_len (по умолчанию 4 символа).

То же ограничение длины используется для поискового запроса. По этой причине поиск e-magazine возвращает точно такие же результаты, что и a-magazine, поскольку a и - полностью игнорируются.

Но теперь вы хотите найти точную фразу e-magazine. При этом вы используете кавычки, и это совершенно правильный способ поиска фраз, но MySQL не поддерживает операторы для фраз, только для слов:
https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html

С этим модификатором определенные символы имеют особое значение в начале или конце слов в строке поиска

Некоторые люди предлагают использовать следующий запрос:

SELECT id, name 
FROM company 
WHERE MATCH(name) AGAINST('e-magazi*' IN BOOLEAN MODE)
HAVING name LIKE 'e-magazi%';

Как я уже сказал, MySQL игнорирует e- и ищет подстановочное слово magazi*. После того, как эти результаты получены, он использует HAVING для дополнительной фильтрации результатов для e-magazi*, включая e-. По этому вы найдете фразу e-magazine AG. Конечно, HAVING требуется только в том случае, если поисковая фраза содержит подстановочный оператор, и вы никогда не должны использовать кавычки. Этот оператор используется вашим пользователем, а не вами!

Примечание: Пока вы не окружите поисковую фразу %, будут найдены только поля, начинающиеся с этого слова. И вы не хотите его окружать, потому что он также найдет bee-magazine. Поэтому, возможно, вам понадобится дополнительный OR HAVING name LIKE ' %e-magazi%' OR HAVING NAME LIKE '\\n%e-magazi%', чтобы использовать его внутри текстов.

Trick

Но, наконец, я предпочитаю трюк, поэтому HAVING совсем не нужен:

  1. Если вы добавляете тексты в таблицу базы данных, добавьте их дополнительно в отдельный полнотекстовый индексированный столбец и замените слова типа up-to-date на up-to-date uptodate.
  2. Если пользователь ищет up-to-date, замените его в запросе на uptodate.

Таким образом, вы все равно можете найти specific в user-specific, но также up-to-date (и не только date).

Бонус

Если пользователь ищет -well-known huge ports, MySQL воспринимает это как not include *well*, could include *known* and *huge*. Конечно, вы могли бы решить это и с другим дополнительным вариантом запроса, но с помощью вышеприведенного трюка вы удалили дефис, чтобы поисковый запрос выглядел просто так:

SELECT id
FROM texts
WHERE MATCH(text) AGAINST('-wellknown huge ports' IN BOOLEAN MODE)
...