Немецкий акцент Mysql нечувствителен к поиску в полнотекстовом поиске

Возьмем пример таблицы отелей:

CREATE TABLE `hotels` (
  `HotelNo` varchar(4) character set latin1 NOT NULL default '0000',
  `Hotel` varchar(80) character set latin1 NOT NULL default '',
  `City` varchar(100) character set latin1 default NULL,
  `CityFR` varchar(100) character set latin1 default NULL,
  `Region` varchar(50) character set latin1 default NULL,
  `RegionFR` varchar(100) character set latin1 default NULL,
  `Country` varchar(50) character set latin1 default NULL,
  `CountryFR` varchar(50) character set latin1 default NULL,
  `HotelText` text character set latin1,
  `HotelTextFR` text character set latin1,
  `tagsforsearch` text character set latin1,
  `tagsforsearchFR` text character set latin1,
  PRIMARY KEY  (`HotelNo`),
  FULLTEXT KEY `fulltextHotelSearch` (`HotelNo`,`Hotel`,`City`,`CityFR`,`Region`,`RegionFR`,`Country`,`CountryFR`,`HotelText`,`HotelTextFR`,`tagsforsearch`,`tagsforsearchFR`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;

В этой таблице, например, есть только один отель с названием региона = "Graubünden" (обратите внимание на умлаут ü).

И теперь я хочу добиться такого же соответствия поиска для фраз: «граубюнден» и «граубюнден».

Это просто с использованием встроенных в MySql сопоставлений при обычном поиске следующим образом:

SELECT *  
FROM `hotels` 
WHERE `Region` LIKE CONVERT(_utf8 '%graubunden%' USING latin1) 
COLLATE latin1_german1_ci

Это отлично работает для «graubunden» и «graubünden», и в результате я получаю правильный результат, но проблема заключается в том, когда мы делаем полнотекстовый поиск MySQL.

Что не так с этим оператором SQL?:

SELECT 
 *
FROM 
 hotels 
WHERE 
 MATCH (`HotelNo`,`Hotel`,`Address`,`City`,`CityFR`,`Region`,`RegionFR`,`Country`,`CountryFR`, `HotelText`, `HotelTextFR`, `tagsforsearch`, `tagsforsearchFR`)
AGAINST( CONVERT('+graubunden' USING latin1)  COLLATE latin1_german1_ci IN BOOLEAN MODE)            
ORDER BY Country ASC, Region ASC, City ASC

Это не возвращает никакого результата. Есть идеи, где зарыта собака?


person denesis    schedule 27.04.2010    source источник


Ответы (1)


Когда вы определяете отдельные CHARACTER SETS для своих столбцов, вы переопределяете параметры сортировки, установленные по умолчанию на уровне таблицы.

Каждый из ваших столбцов имеет сортировку по умолчанию latin1 (то есть latin1_swedish_ci). Вы можете увидеть это, запустив SHOW CREATE TABLE.

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

Вам нужно удалить определения CHARACTER SET из ваших столбцов или явно установить для всех столбцов значение latin1_german_ci:

CREATE TABLE `hotels` (
  `HotelNo` varchar(4) NOT NULL default '0000',
  `Hotel` varchar(80) NOT NULL default '',
  `City` varchar(100) default NULL,
  `CityFR` varchar(100) default NULL,
  `Region` varchar(50) default NULL,
  `RegionFR` varchar(100) default NULL,
  `Country` varchar(50) default NULL,
  `CountryFR` varchar(50) default NULL,
  `HotelText` text,
  `HotelTextFR` text,
  `tagsforsearch` text,
  `tagsforsearchFR` text,
  PRIMARY KEY  (`HotelNo`),
  FULLTEXT KEY `fulltextHotelSearch` (`HotelNo`,`Hotel`,`City`,`CityFR`,`Region`,`RegionFR`,`Country`,`CountryFR`,`HotelText`,`HotelTextFR`,`tagsforsearch`,`tagsforsearchFR`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;

INSERT
INTO    hotels (hotelText, HotelTextFR, tagsforsearch, tagsforsearchFR)
VALUES  ('text', 'text', 'graubünden', 'tags');

SELECT  *
FROM    hotels
WHERE   MATCH (`HotelNo`,`Hotel`,`City`,`CityFR`,`Region`,`RegionFR`,`Country`,`CountryFR`, `HotelText`, `HotelTextFR`, `tagsforsearch`, `tagsforsearchFR`)
AGAINST (CONVERT('+graubunden' USING latin1) COLLATE latin1_german1_ci IN BOOLEAN MODE)
ORDER BY
        Country ASC, Region ASC, City ASC;
person Quassnoi    schedule 27.04.2010
comment
Это 100% правда. Большое спасибо! - person denesis; 27.04.2010