【问题标题】:Mysql german accents not-sensitive search in full-text searches全文搜索中的Mysql德语口音不敏感搜索
【发布时间】:2011-02-12 21:40:32
【问题描述】:

让我们有一个示例酒店表:

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;

例如,在此表中,我们只有一家酒店的 Region name = "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

这不会返回任何结果。 有什么想法把狗埋在哪里?

【问题讨论】:

    标签: mysql encoding full-text-search collation diacritics


    【解决方案1】:

    当您为列定义单独的 CHARACTER SETS 时,您会覆盖您在表级别设置的默认排序规则。

    您的每一列都有默认的latin1 排序规则(即latin1_swedish_ci)。你可以通过运行SHOW CREATE TABLE看到它。

    FULLTEXT 查询中,索引列有COERCIBILITY0,即所有全文查询都转换为索引中使用的排序规则,反之亦然。

    您需要从列中删除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;
    

    【讨论】:

    • 这是 100% 正确的。非常感谢!
    猜你喜欢
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多