MariaDB全文搜索,带有特殊字符和“单词开头”

时间:2018-10-25 10:11:30

标签: full-text-search mariadb fulltext-index

我可以做一个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

将“ *”放在带引号的字符串中将不会返回任何结果(按预期):

select * from mytable
where match(mycol) against ('+"test-serv*"' in boolean mode)>0.0;

有人知道这是否是MariaDB的限制吗?还是错误?

我的MariaDB版本是10.0.31

1 个答案:

答案 0 :(得分:1)

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字符串中。

因此,您的代码的算法类似于:

  1. 以与FULLTEXT相同的方式将字符串分解为“单词”。
  2. 抛弃任何太短的字符串。
  3. 如果没有剩余的单词,那么您将无法使用FULLTEXT并陷入缓慢的LIKE
  4. 在最后一个字词(或每个字词?)后面贴上*
  5. 用这些词构建AGAINST
  6. AND LIKE '%...%'上加上原始词组,并适当转义。