首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >布尔模式下的MySQL FullText :搜索字符串中包含“+”的关键字

布尔模式下的MySQL FullText :搜索字符串中包含“+”的关键字
EN

Stack Overflow用户
提问于 2019-02-22 00:23:12
回答 2查看 1.6K关注 0票数 2

我看过十几个类似的问题,没有运气。我理解在布尔模式下附加到全文关键字的+有一个特殊的含义,但是,如果我们的关键字实际上包含+符号作为文本/字符串的后缀部分,该怎么办?我们如何才能使用全文搜索并得到适当的结果?

数据库结构

代码语言:javascript
复制
CREATE TABLE `ft_test` (
  `i_id` int(11) NOT NULL,
  `i_desc` mediumtext NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `ft_test`
  ADD PRIMARY KEY (`i_id`) USING BTREE;
ALTER TABLE `ft_test` ADD FULLTEXT KEY `i_desc` (`i_desc`);

ALTER TABLE `ft_test`
  MODIFY `i_id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;

数据库数据

代码语言:javascript
复制
SELECT * FROM ft_test;
+------+-----------+
| i_id | i_desc    |
+------+-----------+
|    1 | test      |
|    2 | test+     |
|    3 | test++    |
|    4 | test +    |
|    5 | test plus |
+------+-----------+

测试1:类似的查询

代码语言:javascript
复制
SELECT * FROM ft_test WHERE i_desc LIKE 'test+%';
+------+--------+
| i_id | i_desc |
+------+--------+
|    2 | test+  |
|    3 | test++ |
+------+--------+

测试2:全文查询

代码语言:javascript
复制
SELECT *, MATCH(`i_desc`) AGAINST ('"test+"' IN BOOLEAN MODE) AS RELEVANCE
    -> FROM `ft_test`
    -> WHERE MATCH(`i_desc`) AGAINST ('"test+"' IN BOOLEAN MODE)
    -> ORDER BY RELEVANCE;

+------+-----------+-----------+
| i_id | i_desc    | RELEVANCE |
+------+-----------+-----------+
|    1 | test      |         1 |
|    2 | test+     |         1 |
|    3 | test++    |         1 |
|    4 | test +    |         1 |
|    5 | test plus |         1 |
+------+-----------+-----------+

如您所见,与类似的查询实际上返回并对结果进行了更好的排序。我也尝试过使用引号进行精确匹配,同样的结果。添加“test+”这样的特殊角色也没有帮助。然而,英国“金融时报”的结果并非毫无用处,但它们并不完美,因为排序并非我所期望的那样。

问题

实际上,是否有可能实现这一目标并返回与使用全文模式相同的结果?如果是,怎么做?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-22 00:58:28

只有将列定义为使用将字符视为普通字母(而不是标点符号)的排序规则时,才能对标点符号进行索引。

有一个手册页面显示了执行此操作的步骤:https://dev.mysql.com/doc/refman/8.0/en/full-text-adding-collation.html

但是,由于您说您的脚本是硬编码的,我认为您没有权限重新定义要搜索的列的排序规则,或者在安装自定义排序规则定义后重新启动MySQL服务器。

解决办法是在没有标点符号的情况下搜索单词,然后在找到匹配的单词后添加要应用的条件。

代码语言:javascript
复制
SELECT *, MATCH(`i_desc`) AGAINST ('"test"' IN BOOLEAN MODE) AS RELEVANCE
FROM `ft_test`
WHERE MATCH(`i_desc`) AGAINST ('"test"' IN BOOLEAN MODE)
 AND i_desc LIKE 'test+%';
ORDER BY RELEVANCE;

它将使用全文索引查找与单词匹配的行,然后另一个条件项将针对包含+的字符串的行集(希望是较小的)进行筛选。

但是,如果您没有任何权限来更改SQL查询,这是没有意义的。

票数 1
EN

Stack Overflow用户

发布于 2019-02-22 00:58:59

MySQL全文搜索不识别特殊字符。它只用于搜索单词字符,而+则不是。

如果要对特殊字符进行筛选,则需要LIKE

此外,对于InnoDB,+符号只有放在单词之前而不是后面才有特殊的含义。因此,您的查询实际上相当于:

代码语言:javascript
复制
MATCH(`i_desc`) AGAINST ('"test"' IN BOOLEAN MODE)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54818233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档