二进制模式下的MySQL全文与短语不匹配

eqfvzcg8  于 2022-11-21  发布在  Mysql
关注(0)|答案(2)|浏览(119)

bounty将在2天后过期。回答此问题可获得+200声望奖励。jor正在寻找来自知名来源的答案

实现一个简单的全文搜索时,我遇到了一个布尔模式短语组合的问题。另外值得注意的是,列有一个二进制排序规则(utf8_bin),而表没有。
假设设置如下:

CREATE TABLE `test` (
  `test_id` int(11) NOT NULL AUTO_INCREMENT,
  `text_bin` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`test_id`),
  FULLTEXT KEY `text_bin` (`text_bin`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `test` (`test_id`, `text_bin`) VALUES
(1, 'Lorem Ipsum Dolor Sit Amet.'),
(2, 'Consectetuer Adipiscing Elit.'),
(3, 'Amet Sit Dolor Ipsum Lorem.')
;

然后运行此查询:

SELECT t.test_id, t.text_bin,
  MATCH(t.text_bin) AGAINST ('Lorem Ipsum' IN BOOLEAN MODE) as m_Words,
  MATCH(t.text_bin) AGAINST ('"Lorem Ipsum"' IN BOOLEAN MODE) as m_Phrase,
  MATCH(t.text_bin) AGAINST ('Lorem' IN BOOLEAN MODE) as m_Lorem,
  MATCH(t.text_bin) AGAINST ('Ipsum' IN BOOLEAN MODE) as m_Ipsum
FROM test t
;

这会产生下列结果:
| 测试标识|文本框|m_字|m_短语|m_洛雷姆|m_Ipsum|
| - -|- -|- -|- -|- -|- -|
| 一个|洛伦·伊普苏姆·多洛·西蒂·阿梅特|0.0620单位|第0页|0.0310单位|0.0310单位|
| 2个|无脂饮食|第0页|第0页|第0页|第0页|
| 三个|阿米特·席特·多洛·伊普桑·洛伦。|0.0620单位|第0页|0.0310单位|0.0310单位|
(Note:我将数字缩短为小数点后4位,以提高可读性。)
对于列m_Phrase,我希望第一行的值大于0。这是一个bug还是有人能解释一下为什么结果是0?
DB小提琴:https://www.db-fiddle.com/f/8qxR3SiPVtESU3saebhgBG/0

ajsxfq5m

ajsxfq5m1#

我的直觉是这与space定界符有关。
例如,在这个小提琴中,不同的排序规则会给予不同的结果,区分大小写和匹配空格作为文字的一部分-https://www.db-fiddle.com/f/pi78uuA1RCFeToaRH9skcK/2
更新-使用特殊字符(.#*)更新了上面的Fiddle,这些字符与预期的短语匹配。
除了使用不同的归类之外,我不知道您的问题的解决方案-只使用utf8_general_ci
了解您的用例,甚至是您所面临的促使您使用utf8_bin的性能考虑因素,将是一件非常有趣的事情。
更新二:
这看起来像一个报告的bug。虽然,从2018年...一个修复似乎是降级到版本5.7.19
看起来似乎没有一个最新版本的方法可以同时处理基于FULLTEXT的查询和区分大小写。非常非常奇怪。最简单(不完美)的方法是在每个单词前加上一个加号+Lorem +Ipsum,但显然会导致一些误报。(请参阅上面的m_allm_AllLower字段。

balp4ylt

balp4ylt2#

在8.0.31中仍然失败。
这可能是一种解决方法:

WHERE MATCH(t.text_bin) AGAINST ('+Lorem +Ipsum' IN BOOLEAN MODE)
  AND t.text_bin LIKE '%Lorem Ipsum%'

也就是说,避免FT中的短语测试,并使用LIKE作为辅助过滤器来检查短语。
唉,它不会让你显示相关性。

相关问题