如何在MariaDB多列全文索引中搜索包含多个单词前缀的整体?

问题描述 投票:0回答:1

我有一个存储人名的表

CREATE TABLE `person` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(100) NOT NULL,
  `last_name` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `first_name_last_name` (`first_name`,`last_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `person` (`first_name`, `last_name`) VALUES
('Aristide',    'Romano'),
('Jérôme',  'Nadeau'),
('Madeleine',   'Roger'),
('Daniel',  'De Jong'),
('Alban',   'Hervé'),
('Camille', 'Evrard'),
('Delphine',    'Vriaud'),
('Pavel',   'Lelièvre'),
('Albert',  'De Vries'),
('Luc', 'Robin'),
('Vanessa', 'Olivier'),
('Georges', 'De Vries'),
('Delphine', 'Bernard');

注意:这些是随机生成的名字的摘录,而不是真实的人。

当用户搜索“de vr”时,我想返回包含以“de”开头的单词以“vr”开头的单词的所有行:

  • Delphine Vriaud
  • 阿尔伯特DeVries
  • 乔治DeVries

真实的表当然要大得多(大约 10,000 行),并且查询会经常使用,这就是为什么我尝试使用全文搜索而不是繁重的

column LIKE "{search}%"

我无法使用全文搜索中的默认“按相关性排序”,因为始终根据用户输入应用自定义 ORDER BY 子句。我需要查询仅返回这些行,因为如果它们在部分匹配中被稀释,我不能指望好的结果会出现在顶部。 根据

MariaDB 文档中的运算符描述

,我认为正确的方法是: SELECT * FROM person WHERE MATCH (first_name, last_name) AGAINST ('+de*, +vr*' IN BOOLEAN MODE) ORDER BY last_name, first_name;

*

的意思是“我接受这个词或这样开头的词...”,“+”的意思是“所有结果必须与这个词匹配”。

但是此查询仅返回“Delphine Vriaud”。看来匹配项必须位于不同的列中,从而防止姓氏“De Vries”匹配。

如果我从查询中删除

+

符号:

SELECT * FROM person
WHERE MATCH (first_name, last_name) AGAINST ('de*, vr*'  IN BOOLEAN MODE)
ORDER BY last_name, first_name;

我得到了包含“de*”或“vr*”的所有行,如预期的那样,其中包括我想要的 3 行

我不想要的“Delphine Bernard”。 您可以尝试

在这个小提琴上

的查询。 我想要通过全文搜索实现的目标是否可行?

编辑:我后来发现InnoDB变量

innodb_ft_min_token_size

定义了全文索引中必须包含的单词的最小长度。该变量的默认值为 3,这意味着“De Vries”或“De Jong”中的“De”一词不在索引中,可以解释结果。 我已在本地 MariaDb 服务器上将值更改为 2 并再次尝试,但结果没有改变。

mariadb full-text-search innodb
1个回答
0
投票

SELECT * FROM person WHERE MATCH (first_name, last_name) AGAINST ('de*,+vr*' IN BOOLEAN MODE) ORDER BY last_name, first_name;

© www.soinside.com 2019 - 2024. All rights reserved.