【问题标题】:MySQL searching for containing characters with FULLTEXTMySQL 使用 FULLTEXT 搜索包含的字符
【发布时间】:2015-08-28 18:22:18
【问题描述】:

我想升级我当前的 SQL 搜索查询:

SELECT * FROM aab_movies WHERE title LIKE '%the walking%'

对于一个经过优化的搜索查询,如下所示:

SELECT * FROM aab_movies WHERE MATCH(title) AGAINST('+the +walking' IN BOOLEAN MODE)

两个查询都可以工作,但“很好”优化的查询有一个问题。这不是检索正确的数据。每当我搜索步行时,我只想要开始或包含“步行”的项目。现在它会检索包括“the”和“walking”在内的所有内容(单元格中每个单词的一种分隔)。

谁能解释/帮助我达到我想要的结果?将不胜感激!

简而言之:我想检索以 OR 开头的数据,它包含给定的(整个)字符串(而不是将每个单词分开,然后将它们与给定的字符串进行比较)。

【问题讨论】:

  • 将值放在引号中。
  • @chris85 我该如何处理多个值?
  • 没错。 match(title) against('the walk' IN BOOLEAN MODE)
  • dev.mysql.com/doc/refman/5.6/en/fulltext-boolean.html '"some words"' - “查找包含确切短语“某些词”的行(例如,包含“一些智慧词”但不包含“一些干扰词”的行)。”
  • @jkavalik 我已经读过了,但是在搜索“The Walking”时,我如何找到另一个值,例如“Walking the way off”?

标签: php mysql full-text-search wildcard sql-like


【解决方案1】:

你想要的查询是:

SELECT *
FROM aab_movies
WHERE MATCH(title) AGAINST('"the walking"' IN BOOLEAN MODE)

但是,有两个注意事项。一,你必须非常小心最小字长和术语长度。这可能会排除三个字母的单词(取决于构建索引时使用的设置)。

其次,您必须非常非常小心停用词列表。像“the”这样的词会被自动删除,所以你需要调整停用词列表。

您可以考虑这样构建查询:

SELECT m.*
FROM (SELECT m.*
      FROM aab_movies m
      WHERE MATCH(title) AGAINST('+the +walking' IN BOOLEAN MODE)
     ) m
WHERE title like '%the walking%';

在许多情况下,内部查询只返回少数几行。外部查询然后使用like,但这是在如此小的数据集上,性能可能完全可以接受。

【讨论】:

  • 我认为您可以在同一个查询中执行 MATCH 和 LIKE,只需使用 AND。
  • 感谢您的宝贵时间,但我已经远离 LIKE 语句(因为大型数据库的性能真的很差)。我实际上喜欢使用 FULLTEXT 重建 LIKE 语句。所以基本上,所有包含或以给定字符串开头的东西都必须显示出来。
  • @Testuser070 这背后的想法是 MATCH 只找到几行可能包含您想要的内容,并且只检查那些 - 这样性能不会降低。
  • @jkavalik 使用智能范围后性能不是更好吗?例如字符串“The walk”,它只会在 T & W 范围内搜索,对吧?
  • @Testuser070 我认为全文索引根本不使用范围,但它绝对可以比 LIKE 更快地找到相关行。检查sqlfiddle.com/#!9/ff5ba/1sqlfiddle.com/#!9/ff5ba/2 - 第一个显示了“the”太短且太常见的单词无法被索引的问题,但第二个显示了这个答案中的想法。您可以查看View Execution Plan 按钮以查看索引使用情况。
【解决方案2】:

没关系,我已经设法解决了(当然是在回答这个话题的人的帮助下)。

我使用的引擎 (innoDB) 没有停用停用词列表。我已经配置了 my.ini,并应用了以下规则

[mysqld]
innodb_ft_min_token_size = 1
innodb_ft_enable_stopword = ''
ft_min_word_len = 1
ft_stopword_file = ''

这些基本上是禁用停用词列表并将最小字长最小化为 1。完成此操作后,您必须修复已设置的表(如果 FULLTEXT)。

SELECT * FROM aad_movies WHERE MATCH(title) AGAINST('"the walking"' IN BOOLEAN MODE)

查询是否正确:)

【讨论】:

    猜你喜欢
    • 2010-11-22
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    • 2010-10-14
    • 1970-01-01
    • 2011-05-25
    相关资源
    最近更新 更多