带有特殊字符和 "word starts with" 的 MariaDB 全文搜索
MariaDB fulltext search with special chars and "word starts with"
我可以执行 MariaDB 全文查询来搜索这样开头的单词:
select * from mytable
where match(mycol) against ('+test*' in boolean mode)>0.0;
这会找到像 "test"、"tester"、"testing".
这样的词
如果我的搜索字符串包含特殊字符,我可以将搜索字符串放在引号中:
select * from mytable
where match(mycol) against ('+"test-server"' in boolean mode)>0.0;
这将查找包含字符串 test-server
.
的所有行
但我似乎无法将两者结合起来:
select * from mytable
where match(mycol) against ('+"test-serv"*' in boolean mode)>0.0;
这会导致错误:
Error: (conn:7) syntax error, unexpected $end, expecting FTS_TERM or FTS_NUMB or '*'
SQLState: 42000
ErrorCode: 1064
在引用的字符串中放置 ´*´ 将 return 没有结果(如预期的那样):
select * from mytable
where match(mycol) against ('+"test-serv*"' in boolean mode)>0.0;
有谁知道这是否是 MariaDB 的限制?还是错误?
我的 MariaDB 版本是 10.0.31
WHERE MATCH(mycol) AGAINST('+test +serv*' IN BOOLEAN MODE)
AND mycol LIKE '%test_serv%'
MATCH
将找到所需的行以及一些不需要的行。 然后 LIKE
将过滤掉无效的。由于 LIKE
仅应用于某些行,因此它的缓慢被掩盖了。
(当然,这并非在所有情况下都有效。它需要一些手动操作。)
d'Artagnan
- 使用
WHERE MATCH(mycol) AGAINST("+Arta*" IN BOOLEAN MODE)
AND mycol LIKE '%d\'Artagnan%'
请注意,我使用适当的转义将撇号放入 LIKE
字符串。
所以,你的代码的算法是这样的:
- 按照
FULLTEXT
的方式将字符串分成 "words"。
- 扔掉任何太短的字符串。
- 如果没有留下任何单词,那么您将无法使用
FULLTEXT
并卡在缓慢的 LIKE
。
- 在最后一个词(或每个词?)后粘贴
*
。
- 用这些词构建
AGAINST
。
- 在
AND LIKE '%...%'
上添加原始短语,适当转义。
我可以执行 MariaDB 全文查询来搜索这样开头的单词:
select * from mytable
where match(mycol) against ('+test*' in boolean mode)>0.0;
这会找到像 "test"、"tester"、"testing".
这样的词如果我的搜索字符串包含特殊字符,我可以将搜索字符串放在引号中:
select * from mytable
where match(mycol) against ('+"test-server"' in boolean mode)>0.0;
这将查找包含字符串 test-server
.
但我似乎无法将两者结合起来:
select * from mytable
where match(mycol) against ('+"test-serv"*' in boolean mode)>0.0;
这会导致错误:
Error: (conn:7) syntax error, unexpected $end, expecting FTS_TERM or FTS_NUMB or '*'
SQLState: 42000
ErrorCode: 1064
在引用的字符串中放置 ´*´ 将 return 没有结果(如预期的那样):
select * from mytable
where match(mycol) against ('+"test-serv*"' in boolean mode)>0.0;
有谁知道这是否是 MariaDB 的限制?还是错误?
我的 MariaDB 版本是 10.0.31
WHERE MATCH(mycol) AGAINST('+test +serv*' IN BOOLEAN MODE)
AND mycol LIKE '%test_serv%'
MATCH
将找到所需的行以及一些不需要的行。 然后 LIKE
将过滤掉无效的。由于 LIKE
仅应用于某些行,因此它的缓慢被掩盖了。
(当然,这并非在所有情况下都有效。它需要一些手动操作。)
d'Artagnan
- 使用
WHERE MATCH(mycol) AGAINST("+Arta*" IN BOOLEAN MODE)
AND mycol LIKE '%d\'Artagnan%'
请注意,我使用适当的转义将撇号放入 LIKE
字符串。
所以,你的代码的算法是这样的:
- 按照
FULLTEXT
的方式将字符串分成 "words"。 - 扔掉任何太短的字符串。
- 如果没有留下任何单词,那么您将无法使用
FULLTEXT
并卡在缓慢的LIKE
。 - 在最后一个词(或每个词?)后粘贴
*
。 - 用这些词构建
AGAINST
。 - 在
AND LIKE '%...%'
上添加原始短语,适当转义。