【问题标题】:Mysql query match against multiple possible charactersMysql查询匹配多个可能的字符
【发布时间】:2012-09-19 11:26:54
【问题描述】:

我有以下问题

SELECT * 
FROM  `articles` 
WHERE (
        (
        UCASE(  `title` ) LIKE UCASE(  '% Fishoil %' ) 
        AND UCASE(  `title` ) LIKE UCASE(  '% for %' ) 
        AND UCASE(  `title` ) LIKE UCASE(  '% more %' ) 
        AND UCASE(  `title` ) LIKE UCASE(  '% musclemass %' )
        )
    OR (
        UCASE(  `text` ) LIKE UCASE(  '% Fishoil %' ) 
        AND UCASE(  `text` ) LIKE UCASE(  '% for %' ) 
        AND UCASE(  `text` ) LIKE UCASE(  '% more %' ) 
        AND UCASE(  `text` ) LIKE UCASE(  '% musclemass %' )
        )
    OR (
        UCASE(  `source` ) LIKE UCASE(  '% Fishoil %' ) 
        AND UCASE(  `source` ) LIKE UCASE(  '% for %' ) 
        AND UCASE(  `source` ) LIKE UCASE(  '% more %' ) 
        AND UCASE(  `source` ) LIKE UCASE(  '% musclemass %' )
        )
    OR (
        UCASE(  `unique` ) LIKE UCASE(  '% Fishoil %' ) 
        AND UCASE(  `unique` ) LIKE UCASE(  '% for %' ) 
        AND UCASE(  `unique` ) LIKE UCASE(  '% more %' ) 
        AND UCASE(  `unique` ) LIKE UCASE(  '% musclemass %' )
        )
    )
ORDER BY  `year` DESC

我想做的,就是改变

UCASE(  `tile` ) LIKE UCASE(  '% Fishoil %' )

进入

 UCASE(  `title` ) LIKE UCASE(  '%Fishoil %' ) 
OR 
    UCASE(  `title` ) LIKE UCASE(  '%Fishoil,%' ) 
OR 
    UCASE(  `title` ) LIKE UCASE(  '%Fishoil.%' ) 
OR 
    UCASE(  `title` ) LIKE UCASE(  '%Fishoil:%' ) 
OR 
    UCASE(  `title` ) LIKE UCASE(  '%Fishoil;%' ) 
OR 
    UCASE(  `title` ) LIKE UCASE(  '%Fishoil\'%' ) 
OR 
    UCASE(  `title` ) LIKE UCASE(  '%Fishoil"%' ) 
OR 
    UCASE(  `title` ) LIKE UCASE(  '%Fishoil!%' ) 
OR 
    UCASE(  `title` ) LIKE UCASE(  '%Fishoil?%' )

但在我看来,这使查询变得异常复杂,因为它必须进行多次匹配。是否有一种正则表达式可以一次性匹配“搜索词+特殊字符”?

如果是这样,最好的匹配方法是什么?

这是生成关键字搜索字符串的php代码

$specialchars = array(' ',',','.',':',';',mysql_real_escape_string("'"),'"','!','?');
foreach($seek as $searchword)
    {
    foreach($specialchars as $char)
        {
        $seeker[] = "LIKE UCASE(  '%$searchword".$char."%' )";
        }
    $temp = implode(" OR ",$seeker);
    echo $temp;
    }

【问题讨论】:

  • 您的查询没有那么复杂,只是非常slooooooooow:几乎可以保证会减慢查询速度的三件事:过度使用通配符 (%):检查. WHERE 子句中有多个OR:检查。索引错误(可能检查)
  • 是的,它是一个搜索引擎,可以在数字图书馆中搜索 100 个单词的文本。尝试不使用通配符进行搜索。我可以使用建议来优化它。索引被照顾。我只需要一种更好的方法来进行查询,最好是正则表达式。

标签: php mysql search sql-like


【解决方案1】:

我建议您使用regular expressions,因为它们比通配符LIKE 语法强大得多。通过使用正则表达式,您可以将整组条件放入一个 REGEXP 调用中(每列)。

【讨论】:

  • 好的,这是我可以做点什么的建议。我一直在寻找这种东西,但找不到。我认为谷歌搜索不好。我会努力解决这个问题。感谢您的链接!
  • 如果您使用 UTF8 排序规则(可能就是这种情况),但鉴于 PHP 标记,MySQL 的 REGEXP 引擎可能会产生意想不到的结果。谷歌了解更多信息,但here's a page on the mysql site that mentions this
  • 还有其他注意事项,例如LIKE 在某些情况下可能会使用索引,这与正则表达式不同。不过,你的情况并非如此。
【解决方案2】:

不要为每个字符添加 or 子句,而是使用下划线 (_)。这就像一个通配符,除了一件事:它是单个字符的占位符:

SELECT * FROM foo WHERE bar LIKE 'visolie_';

匹配 visolie!、visolie:、visolie? 和 - 因为类似 不区分大小写 ViSOliE!。

编辑:

出于所有意图和目的:有许多优秀的搜索引擎是由非常聪明的人编写的,并且仍在由一群称职的程序员进一步开发。尝试创建自己的 SE 可能是一个很好的练习,但是当它真正归结为它时,只需使用 CSE
他们已经为你完成了艰苦的工作,作为一名开发人员意味着在聪明的情况下懒惰方法。开源软件以及网络的全部意义在于避免不断重复发明轮子的必要性。

如果您绝对想构建自己的 SE,PHP 和 MySQL 是经过验证的技术,但可能不是完成这项工作的最佳工具。尝试寻找更快的数据库(NoSQL?)替代品(MongoDB 会浮现在脑海中,只要您不经常更新数据,它的速度非常快。再次:选择一个意味着失去另一个,您的数据并不安全存储...)。
PHP 相当快,但与 C++ 相比,它占用了大量资源。我不确定我是否做对了,但我准备赌一大笔钱,说 SE 就像谷歌,雅虎!甚至糟糕的旧 Bing 在某处也有相当庞大的 C(++) 代码库。迄今为止没有任何脚本语言可以超越它,(而且 IMO 永远不会有脚本语言可以)

【讨论】:

  • 这可能无法按预期工作,因为“visolieW”也会被匹配。 _ 代表任何字符。
  • 我不想匹配所有东西。这也将与我不想要的 visolien 相匹配。 @shedal 说了什么。
  • @MichaelDibbets: 是的,但是这个匹配visoliecapsules,而你目前的做法不会。正如您所说,您正在构建一个搜索引擎,这完全是关于选择,利弊。完美的引擎是不存在的,这就是为什么 google 和 co 不断发展的原因。在谷歌上:他们为你发明了轮子,为什么不使用他们的custom search engine?你自己永远不会得到这么好的东西!请记住:作为开发人员意味着聪明地偷懒
  • @MichaelDibbets:我已经编辑,或者更确切地说,在我的回答中添加了一些 “建议”。如果您正在构建 SE,我会说查询不应超过 SE 整体速度的 15%
  • 这在待办事项列表中以供将来参考。
【解决方案3】:

可能值得关注FULLTEXT

你可以这样做;

SELECT *, MATCH(title,text,source,unique) AGAINST('fishoil for more musclemass') AS `score` FROM `articles` WHERE MATCH(title,text,source,unique) AGAINST('fishoil for more musclemass') ORDER BY `score` DESC, `year` DESC

whcih 将首先返回最相关的结果。

您也必须更改您的 SQL 表;

ALTER TABLE articles ADD FULLTEXT(title,text,source,unique);

希望对你有帮助

【讨论】:

  • 抱歉,对每一次搜索执行这种操作的搜索引擎对您的服务器来说是毁灭性的......
猜你喜欢
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多