MySQL MATCH() AGAINST() FULLTEXT索引——实现部分字符串匹配与短语匹配相结合

4 mysql string against match match-against

我有一个表,其中的列内容具有FULLTEXT 索引

\n

我想利用MATCH()在大文本上的速度。

\n

我希望搜索尽可能准确。

\n

当我这样搜索短语字符串“ large Truck ”时:

\n
SELECT * FROM MyTable WHERE MATCH(content) AGAINST('"large truck"' IN BOOLEAN MODE);\n
Run Code Online (Sandbox Code Playgroud)\n

有些实例被遗漏了。

\n

我的表:

\n
|   content    |\n----------------\n|Large \\n truck| FOUND \xe2\x9c\x93\n----------------\n|large truck   | FOUND \xe2\x9c\x93\n----------------\n|large trucks  | *PLURAL MISSED!\n----------------\n|large truckl  | *TYPE-O MISSED!\n
Run Code Online (Sandbox Code Playgroud)\n

如果我使用标准的LIKE /通配符方法:

\n
SELECT * FROM  `MyTable` WHERE  `content` LIKE  '%large truck%'\n
Run Code Online (Sandbox Code Playgroud)\n

我的表:

\n
|   content    |\n----------------\n|Large \\n truck| *MISSED!\n----------------\n|large truck   | FOUND \xe2\x9c\x93\n----------------\n|large trucks  | FOUND \xe2\x9c\x93\n----------------\n|large truckl  | FOUND \xe2\x9c\x93\n
Run Code Online (Sandbox Code Playgroud)\n

看来我也不能将 PHRASE 搜索与通配符一起使用:

\n
SELECT * FROM MyTable WHERE MATCH(content) AGAINST('"large truck*"' IN BOOLEAN MODE); **DOES NOT WORK**\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
SELECT * FROM MyTable WHERE MATCH(content) AGAINST('"large truck"*' IN BOOLEAN MODE); **DOES NOT WORK**\n
Run Code Online (Sandbox Code Playgroud)\n

所以...

\n

如何成功使用 MATCH() AGAINST() 搜索短语,并获取返回的所有实例 - 即使不区分大小写的部分字符串匹配?

\n

Ric*_*mes 5

我经常使用 FT 的技巧是分两步进行:

  1. 执行MATCH,希望获得所有所需的文本,但可能会获得一些额外的结果。
  2. AND与另一个条件 - LIKE(更快)或REGEXP(更强大)。

MATCH由于FT,速度会很快;另一部分将随后执行,因此速度会很快,因为需要检查的行不多。

这符合您的标准:

SELECT * FROM MyTable
    WHERE MATCH(content) AGAINST('+large +truck*' IN BOOLEAN MODE)
      AND content REGEXP "large[[:space:]]+truck";
Run Code Online (Sandbox Code Playgroud)

换句话说,查询将运行如下所示的内容:

  1. 假设该表有 10K 行。
  2. 将评估 FT 表达式。速度MATCH会非常快(因为它的设计方式)。它将在 中的任何位置找到同时包含“large”和“truck*”的所有行content。现在,假设有 30 行满足该要求。
  3. 其余的WHERE进行评估。但它仅针对那 30 行完成。因此,尽管REGEXP成本高昂,但并不经常这样做。
  4. 那么可能会返回 14 行。

最终效果是整个查询运行“快速”,这是您的要求之一。

注意:我需要第二部分来防止这些

large green truck
the truck is large
Run Code Online (Sandbox Code Playgroud)

根据版本的不同,您可能需要此 REGEXP: "large\\s+truck"