Полнотекстовый поиск - это инструмент для эффективного поиска слов (или начала слов), которые появляются в любом месте (полного) текста. Если ваши данные не содержат разделенных «слов» (каким бы способом вы их не определяли), полнотекстовый индекс не является подходящим инструментом для вашей задачи (поскольку он будет совершенно бесполезным). По умолчанию *
- это разделитель слов, как и пробел (например, 'abc*def'
, а также 'abc def'
- это два слова с двумя отдельными записями в полнотекстовом индексе, ни одно из которых не будет содержать *
). , Вы можете указать, что вы хотите использовать в качестве разделителя, но MySQL не поддерживает его определение на лету, экранируя их в поисковом выражении; Вы должны сделать это при создании индекса, чтобы индекс фактически содержал jose*
, а не только jose
.
Если у вас нет слов (или очень ограниченный набор разделителей), вы можете использовать, например, username = 'jose*
, username like 'jose*'
или аналогичный; В качестве альтернативы, вы можете использовать регулярные выражения , которые являются медленными, но резервным инструментом для сложных требований (например, если полный текст не работает для вашей ситуации), когда полнотекстовый индекс не является usabel (и / или вы не можете измените конфигурацию в соответствии с вашими требованиями).
Чтобы изменить символы, которые MySQL рассматривает как разделитель, вы можете изменить карту символов, см. Добавление сопоставления для полнотекстовой индексации :
- добавить новое сопоставление к
index.xml
- добавить это сопоставление в файл символов (например,
latin1.xml
) и отредактировать ctype
, чтобы определить определенный символ как (не) разделитель; только для *
, измените его на "48 10 10 10 10 10 10 10 10 10 01 10 10 10 10 10"); сделайте это для всех символов, которые вы хотите использовать для поиска (но помните, что если у вас нет хотя бы одного оставшегося разделителя, полнотекстовый поиск бесполезен).
- после перезапуска используйте это сопоставление для своего столбца (например,
... (username TEXT collate 'latin1_fulltext_ci', ...
) и заново создайте полнотекстовый индекс, и MySQL включит эти символы в индекс.
- имейте в виду, что вам нужно делать это на каждом сервере, для которого вы хотите использовать это поведение
Теперь следующие три поиска должны вернуть ожидаемые результаты:
... MATCH(username) AGAINST('"jose*"' IN BOOLEAN MODE);
... MATCH(username) AGAINST('jose*');
... MATCH(username) AGAINST('"jose*"');
"..."
будет искать точное совпадение (например, словосочетание); он работает аналогично экранированию, но не совсем, так как применяется только к символам без разделителей.
... MATCH(username) AGAINST('jose*' IN BOOLEAN MODE);
будет не работать для InnoDB (это будет рассматриваться как подстановочный знак), но будет работать для MyISAM (одно из тонких отличий между ними).
Если вы действительно хотите использовать логический режим, но вам нужен подстановочный знак, отличный от *
, вы можете определить другой символ подстановки, используя ft_boolean_syntax
, хотя из-за ошибки в InnoDB это также работает только в MyISAM. Это также глобальная настройка, поэтому изменил бы поведение всех других полнотекстовых поисков в других таблицах (и базах данных). Возможно, вам придется указать, чего вы хотите достичь в этом режиме, чтобы увидеть, есть ли способ заставить полнотекстовый поиск работать с этими требованиями, но в конечном итоге вам, возможно, придется использовать like
.