Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
布尔模式下的MySQL全文:搜索包含'+';作为字符串的一部分_Mysql_Sql_Full Text Search_Mariadb - Fatal编程技术网

布尔模式下的MySQL全文:搜索包含'+';作为字符串的一部分

布尔模式下的MySQL全文:搜索包含'+';作为字符串的一部分,mysql,sql,full-text-search,mariadb,Mysql,Sql,Full Text Search,Mariadb,我看了十几个“类似”的问题,但运气不好。我理解在布尔模式下,全文中附加到关键字的+具有特殊意义, 但是,如果我们的关键字实际上包含+符号作为文本/字符串的后缀部分,该怎么办。我们如何仍然使用全文搜索并获得正确的结果 数据库结构 CREATE TABLE `ft_test` ( `i_id` int(11) NOT NULL, `i_desc` mediumtext NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; ALTER TABLE `f

我看了十几个“类似”的问题,但运气不好。我理解在布尔模式下,全文中附加到关键字的
+
具有特殊意义, 但是,如果我们的关键字实际上包含
+
符号作为文本/字符串的后缀部分,该怎么办。我们如何仍然使用全文搜索并获得正确的结果

数据库结构

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;
数据库数据

SELECT * FROM ft_test;
+------+-----------+
| i_id | i_desc    |
+------+-----------+
|    1 | test      |
|    2 | test+     |
|    3 | test++    |
|    4 | test +    |
|    5 | test plus |
+------+-----------+
测试#1:类似查询

SELECT * FROM ft_test WHERE i_desc LIKE 'test+%';
+------+--------+
| i_id | i_desc |
+------+--------+
|    2 | test+  |
|    3 | test++ |
+------+--------+
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 |
+------+-----------+-----------+
测试2:全文查询

SELECT * FROM ft_test WHERE i_desc LIKE 'test+%';
+------+--------+
| i_id | i_desc |
+------+--------+
|    2 | test+  |
|    3 | test++ |
+------+--------+
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 |
+------+-----------+-----------+
如您所见,LIKE查询在本例中实际返回并对结果进行了更好的排序。我也尝试过使用引号来精确匹配,同样的结果。添加像“test\+”这样的“特殊”字符也没有帮助。尽管如此,金融时报的结果并非毫无用处,而是不够完美,因为排序并不是我所期望的

问题

使用全文模式是否确实可以实现这一点并返回与LIKE中相同的结果?如果是,如何进行


谢谢

如果将列定义为使用将字符视为普通字母而不是标点符号的排序规则,则只能为标点符号编制索引

有一个手册页面显示了执行此操作的步骤:

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

解决方法是搜索不带标点符号的单词,然后在找到匹配的单词后添加要应用的条件

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查询,这是没有意义的。

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

如果要筛选特殊字符,则需要像这样的

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

MATCH(`i_desc`) AGAINST ('"test"' IN BOOLEAN MODE)

如果不需要运算符,为什么要使用布尔模式?它是脚本的一部分,是硬编码的。我不确定+是否被视为单词的一部分。我猜它是一个单词分隔符,因此被排除在全文索引之外,在搜索中被忽略。谢谢比尔,答案被接受。当然,我可以更改源代码,但如果不是真的需要,我会避免它。谢谢。我知道InnoDB的这一部分,这就是它的MyISAM表的原因,是的,它通过比较并得到与最后没有任何特殊字符相同的结果来计算这一部分切换到LIKE的问题是,它必须以某种方式从前端输入进行管理(取决于查询是否包含+,这是逻辑连接还是word的一部分?),而且切换会使搜索变得相当复杂。我接受了比尔上面的回答,因为它恰到好处。