MySQL - ускорение амперсанда (&) в полнотекстовом поиске

Мы используем полнотекстовый поиск для поиска имени компании, и все идет хорошо, пока у нас нет компании с амперсандом в ее имени, например. 'М & S'.

SELECT name FROM company WHERE MATCH (name) against ('M&S' IN BOOLEAN MODE);

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

То, что я ищу, - это способ избежать амперсанда, чтобы MySQL правильно его обрабатывал и нашел запись.

Отслеживание полнотекстового поиска в пользу LIKE не является точно вариантом

Спасибо за помощь

Ответ 1

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

поэтому вам нужно создать собственную сортировку (или перекомпилировать ваш сервер MySQL), где вы добавите & в список символов слова, как я узнал в документах MySQL ( http://dev.mysql.com/doc/refman/5.0/en/fulltext-fine-tuning.html):

Если вы хотите изменить набор символов, которые считаются словом символов, вы можете сделать это несколькими способами, как описано в следующий список. После внесения изменений вы должны восстановить индексы для каждой таблицы, содержащие любые индексы FULLTEXT. предполагать что вы хотите рассматривать символ дефиса ('-') как символ слова. Используйте один из следующих способов:

Измените источник MySQL: в myisam/ftdefs.h см. true_word_char() и misc_word_char(). Добавьте '-' к одному из этих макросов и перекомпилируйте MySQL.

Измените файл набора символов: это не требует перекомпиляции. Массив true_word_char() использует таблицу "тип символа", чтобы различать буквы и цифры от других символов., Вы можете редактировать содержимое массива в одном из XML файлов набора символов для укажите, что "-" - это "письмо". Затем используйте заданный набор символов для ваши индексы FULLTEXT. Сведения о массиве формат, см. раздел 10.3.1, "Матрицы определения символов".

Добавить новую сортировку для набора символов, используемого индексированными столбцами, и измените столбцы, чтобы использовать эту сортировку. Для общей информации о добавлении сопоставлений, см. раздел 10.4, "Добавление сортировки к Набор символов". Для примера, характерного для полнотекстовой индексации, см. Раздел 12.9.7, "Добавление сортировки для полнотекстового индексирования".

UPDATE:, если вы используете латинское сопоставление, откройте файл XML, который находится в mysql/share/charsets/latin1.xml. и найти соответствующий код символа на карте - в этом случае вы можете взять карту для нижнего регистра или верхнего регистра, потому что это не имеет значения для символа амперсанда:

<lower>
<map>
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
 F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF
 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
</map>
</lower>

амперсанд unicode U+0026 и в utf-8, кодирующий его 0x26, поэтому выполните поиск 26 на карте - который находится в третьей строке, 7-й столбец.

то в ctype -map измените тип символа из 10, который означает пунктуацию на 01, что означает маленькую букву:

<ctype>
<map>
 00
 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
 48 10 10 10 10 10 01 10 10 10 10 10 10 10 10 10
 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01
 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
 10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
 00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
 01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
 02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
</map>
</ctype>

перезагрузите сервер MySQL, и соответствующая сортировка обрабатывает &, как будто это была маленькая буква.

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

вы можете найти полную документацию, где я получил большую часть информации отсюда: http://dev.mysql.com/doc/refman/5.0/en/full-text-adding-collation.html

Примечание. Для всех тех, кто работает с версией Mysql 5.7, используйте неиспользуемый идентификатор сопоставления. Статья mysql http://dev.mysql.com/doc/refman/5.0/en/fulltext-fine-tuning.html предназначена для версии Mysql 5.5. Чтобы получить максимальный идентификатор сопоставления, используйте следующий запрос -

   SELECT MAX(ID) FROM INFORMATION_SCHEMA.COLLATIONS;

Ответ 2

ИЗМЕНИТЬ:, так что и разбивает его на два отдельных слова... так как они 1 буква, это ничего не возвращает. Я тестировал "Ma & Sa".. my ft_min_word_len = 4... и он ничего не возвращал, так как длина этой строки > 4, но ее не возвращающая, она должна разбивать ее на два слова... это похоже, предложение, сделанное Northkildonan, - это то, что вам нужно сделать.

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

сначала: запустите этот оператор - SHOW VARIABLES LIKE 'ft_min_word_len'; и подтвердите, что длина фактически равна 2 если я не уверен, что это ничем не отличается от слова длиной более 4

Во-вторых: я сделал это и получил результаты.

НАСТРОЙКА:

Я установил образец таблицы в моей базе данных localhost...

create table company(
`id` int,
`name` varchar(55)
);

insert into company
(`id`, `name`)
values
(1, 'oracle'),
(2, 'microsoft'),
(3, 'M&S'),
(4, 'dell');

ИСПЫТАНИЯ: когда ft_min_word_len = 4 и, очевидно, ничего не вернул.

SELECT `name` FROM company WHERE MATCH (`name`) against ("M&S" IN BOOLEAN MODE);

Я не хотел пытаться перезапустить мою базу данных localhost до reset длины до 2 (если я случайно случайно что-то испортил, потому что я использую ее много).

но у меня возникла идея поиска имени компании, которая была длиннее 4 с помощью и внутри нее.

БОЛЬШЕ НАСТРОЙКИ:

insert into company
(`id`, `name`)
values
(5, 'Mary&Sasha');

ДРУГОЙ ТЕСТ:

SELECT `name` FROM company WHERE MATCH (`name`) against ("Mary&Sasha" IN BOOLEAN MODE); 

это возвращает http://screencast.com/t/Rx8mh98OUp

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

СОТРУДНИЧЕСТВО:

ALTER TABLE company MODIFY
    `name` VARCHAR(55)
      CHARACTER SET latin1
      COLLATE latin1_german2_ci;

вы также можете проверить сортировку таблиц с помощью:

SHOW TABLE STATUS;

надеюсь, что это хоть какая-то помощь:)

Ответ 3

& не является специальным символом в mysql, поэтому вы можете хранить и искать выражение & вы можете проверить это как следует

    SELECT name FROM  `testing` WHERE name LIKE  '%&%'

также попробуйте что-нибудь вроде следующего, чтобы заменить &.

    SET @searchstring = 'M&S';
    SET @searchstring = REPLACE(@searchstring,'&','&amp;');
    SELECT name FROM company WHERE MATCH (name) against (@searchstring IN BOOLEAN MODE);


Вы также можете взглянуть на регулярное выражение. http://dev.mysql.com/doc/refman/5.1/en/regexp.html
Здесь используется и используется как.

    mysql> SELECT '&' REGEXP '[[.ampersand.]]';


Следующий запрос также дает вам результат

    SELECT * 
    FROM  `testing` 
    WHERE  `name` REGEXP CONVERT( _utf8 'M&S'
    USING latin1 ) COLLATE latin1_german2_ci 
    LIMIT 0 , 30

Пожалуйста, прочитайте также эту тему, может быть, вы поймете ее лучше меня. Это SQL, но они, похоже, решили проблему http://forums.asp.net/t/1073707.aspx?Full+text+search+and+sepcial+characters+like+ampersand+

Извините, я больше не мог помочь