MySQL FullText в логическом режиме: поиск ключевых слов, которые содержат «+» как часть строки - PullRequest
0 голосов
/ 22 февраля 2019

Я посмотрел на дюжину «похожих» вопросов, но не повезло.Я понимаю, что +, прикрепленный к ключевому слову в FULLTEXT в режиме BOOLEAN, имеет особое значение, однако, что если наши ключевые слова на самом деле содержат символ + в качестве суффиксной части текста / строки.Как мы все еще можем использовать ПОЛНЫЙ ТЕКСТ для поиска и получения правильных результатов?

СТРУКТУРА БАЗЫ ДАННЫХ

CREATE TABLE `ft_test` (
  `i_id` int(11) NOT NULL,
  `i_desc` mediumtext NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `ft_test`
  ADD PRIMARY KEY (`i_id`) USING BTREE;
ALTER TABLE `ft_test` ADD FULLTEXT KEY `i_desc` (`i_desc`);

ALTER TABLE `ft_test`
  MODIFY `i_id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;

ДАННЫЕ БАЗЫ ДАННЫХ

SELECT * FROM ft_test;
+------+-----------+
| i_id | i_desc    |
+------+-----------+
|    1 | test      |
|    2 | test+     |
|    3 | test++    |
|    4 | test +    |
|    5 | test plus |
+------+-----------+

ТЕСТ № 1: КАК ЗАПРОС

SELECT * FROM ft_test WHERE i_desc LIKE 'test+%';
+------+--------+
| i_id | i_desc |
+------+--------+
|    2 | test+  |
|    3 | test++ |
+------+--------+

ТЕСТ № 2: ПОЛНЫЙ ТЕКСТ

SELECT *, MATCH(`i_desc`) AGAINST ('"test+"' IN BOOLEAN MODE) AS RELEVANCE
    -> FROM `ft_test`
    -> WHERE MATCH(`i_desc`) AGAINST ('"test+"' IN BOOLEAN MODE)
    -> ORDER BY RELEVANCE;

+------+-----------+-----------+
| i_id | i_desc    | RELEVANCE |
+------+-----------+-----------+
|    1 | test      |         1 |
|    2 | test+     |         1 |
|    3 | test++    |         1 |
|    4 | test +    |         1 |
|    5 | test plus |         1 |
+------+-----------+-----------+

Как видите, LIKE запрос фактически вернул и отсортировал результаты лучше в этом случае.Я также пытался использовать кавычки для точного соответствия, те же результаты.Добавление «специальных» символов, таких как «test \ +», также не помогло.В то время как результаты FT не бесполезны, они не идеальны, потому что я не ожидаю, что порядок упорядочен.

ВОПРОС

Реально ли это достичьэто и возвращает те же результаты, что и в LIKE при использовании режима FULLTEXT ?Если да, то как?

Спасибо!

Ответы [ 2 ]

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

Полнотекстовый поиск MySQL не распознает специальные символы.Он предназначен для поиска только для символов слова, которых + нет.

Если вы хотите фильтровать специальные символы, LIKE - это то, что вам нужно.

Также с InnoDBзнак + имеет особое значение, когда он ставится перед только словом, а не после.Таким образом, ваш запрос на самом деле эквивалентен:

MATCH(`i_desc`) AGAINST ('"test"' IN BOOLEAN MODE)
0 голосов
/ 22 февраля 2019

Вы можете индексировать знаки препинания только в том случае, если в столбце определено использование сопоставления, в котором символы обрабатываются как обычные буквы, а не как знаки препинания.

Существует страница руководства, в которой показаны шаги, необходимые для этого: https://dev.mysql.com/doc/refman/8.0/en/full-text-adding-collation.html

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

Обходной путь - поиск слова без пунктуации, а затем добавление условия, которое будет применяться после поиска подходящих слов.

SELECT *, MATCH(`i_desc`) AGAINST ('"test"' IN BOOLEAN MODE) AS RELEVANCE
FROM `ft_test`
WHERE MATCH(`i_desc`) AGAINST ('"test"' IN BOOLEAN MODE)
 AND i_desc LIKE 'test+%';
ORDER BY RELEVANCE;

Он будет использовать полнотекстовый индексчтобы найти строки, соответствующие слову, а затем условие другого условия будет фильтроваться по этому (надеюсь, небольшому) набору строк для тех, у которых есть строка с включенным +.

Но, опять же, если вы неУ вас нет прав для изменения SQL-запроса, это спорный вопрос.

...