Mysql查询匹配多个可能的字符

时间:2012-09-19 11:26:54

标签: php mysql search sql-like

我有以下查询

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?%' )

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

如果是这样,那么匹配它的最佳方法是什么?

这是生成关键字搜索字符串

的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;
    }

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

SELECT * FROM foo WHERE bar LIKE 'visolie_';

匹配visolie!,visolie:,visolie ?,并且 - 因为喜欢的情况不敏感 ViSOliE!也是。

编辑:

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

如果绝对想要构建自己的SE,PHP和MySQL是经过验证的技术,但也许不是最适合这项工作的工具。尝试研究更快的DB(NoSQL?)替代方案(想想MongoDB,只要你不经常更新你的数据,就会非常快。再次:选择一个意味着失去另一个,你的数据就不那么安全了存储...)。
PHP相当快,但与C ++相比占用了大量资源。我不确定我是否做到了这一点,但我准备打赌相当大笔钱,说SE就像谷歌,雅虎!甚至糟糕的旧Bing在某处都有相当庞大的C(++)代码库。到目前为止,没有任何脚本语言可以胜过它,(并且IMO永远不会有可以使用的脚本语言)

答案 2 :(得分:0)

值得一看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);

希望这有帮助