【问题标题】:Php/ MySql 'Advanced Search' PagePHP/MySql“高级搜索”页面
【发布时间】:2010-09-29 05:26:42
【问题描述】:

我正在网站上的“高级搜索”页面上工作,您可以在其中输入关键字,例如“我喜欢苹果”,它可以使用以下选项搜索数据库:

查找:用所有的词,用 确切的短语,至少有一个 话,没有话

我可以通过以下方式处理“精确短语”:

SELECT * FROM myTable WHERE field='$keyword';

'至少一个单词' by:

SELECT * FROM myTable WHERE field LIKE '%$keyword%';//Let me know if this is the wrong approach

但我坚持的是“至少有一个词”和“没有这些词”。

对如何实现这两个有什么建议吗?

编辑:关于“至少一个单词”,使用explode() 将关键字分解为单词并运行循环添加

并不是一个好方法
(field='$keywords') OR ($field='$keywords) (OR)....

因为查询中还有一些其他的 AND/OR 子句,我不知道可以有的最大子句数。

【问题讨论】:

    标签: php mysql sql search


    【解决方案1】:

    我建议将MySQL FullText SearchBoolean Full-Text Searches 功能一起使用,您应该能够获得所需的结果。

    编辑:

    根据您请求的条件请求示例(“它只有一个字段,他们可以选择 4 个选项中的任何一个(即 1 个单词、确切的单词、至少 1 个单词、没有术语)。”)

    我假设您根据您的初始帖子使用 php

    <?php
    $choice = $_POST['choice'];
    $query = $_POST['query'];
    
    if ($choice == "oneWord") {
        //Not 100% sure what you mean by one word but this is the simplest form
        //This assumes $query = a single word
        $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('{$query}' IN BOOLEAN MODE)");
    } elseif ($choice == "exactWords") {
        $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('\"{$query}\"' IN BOOLEAN MODE)");
    } elseif ($choice == "atLeastOneWord") {
        //The default with no operators if given multiple words will return rows that contains at least one of the words
        $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('{$query}' IN BOOLEAN MODE)");
    } elseif ($choice == "withoutTheTerm") {
        $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('-{$query}' IN BOOLEAN MODE)");
    }
    ?>
    

    希望这有助于在布尔匹配中充分利用运算符,请参阅Boolean Full-Text Searches

    【讨论】:

    • +1,这是最好的答案,但我还要详细说明 mysql 上的全文仅适用于 myisam 表,而不适用于 innodb 表。因此,您可以在事务一致性或搜索之间进行选择。
    • 如果您提供一些源代码来显示如何使用全文完成这两个功能(即所有单词和没有单词),我可能会接受您的回答。
    • 我很乐意为您提供一些示例代码。如果您能告诉我,您的搜索表单中是否有两个单独的字段用于使用和不使用,或者您是否使用一个字段?如果它是一个字段,您可以简单地允许用户在想要排除的单词后面加上 -。
    • 它只有一个字段,他们可以选择 4 个选项中的任何一个(即 1 个单词、确切的单词、至少 1 个单词、没有术语)。
    • 好的,我会尽快发布一些基于此的示例代码。
    【解决方案2】:

    你可以使用

    至少有一个字

    SELECT * FROM myTable WHERE field LIKE '%$keyword%' 
    or field LIKE '%$keyword2%' 
    or field LIKE '%$keyword3%';
    

    无话可说

    SELECT * FROM myTable WHERE field NOT LIKE '%$keyword%';
    

    【讨论】:

    • 请看我上面的编辑。您认为这是一个很好的解决方案吗,即可以在查询中放置的 OR 子句的数量是否有任何限制?
    • 可能有一个限制,但我从来没有达到它并且已经做了更长的 where 语句,但是你添加的越多,查询就会越慢,like 特别慢。
    • 没有实际限制。如果您有其他 WHERE 子句,则将关键字搜索括起来:“ WHERE something = x AND (field LIKE ... OR field LIKE ... OR ...)
    【解决方案3】:

    我不确定您是否可以像其他两个一样以幼稚的方式轻松完成这些搜索选项。

    如果您需要支持这些场景,那么实施更好的搜索引擎是值得的。一个简单的可能会让你通过的事情是这样的:

    当一个项目被添加到数据库中时,它会被分割成单独的单词。此时“常用”词(the、a 等)被删除(可能基于 common_words 表)。如果剩余的单词不存在,则将它们添加到单词表中。然后在单词 entry 和 item entry 之间建立了一个链接。

    在搜索时,然后是从单词表中获取单词 id 并在连接表中适当查找项目 id 的情况。

    【讨论】:

      【解决方案4】:

      众所周知,搜索很难做好。

      您应该考虑使用第三方搜索引擎,例如 LuceneSphider

      【讨论】:

        【解决方案5】:

        Giraffe 和 Re0sless 给出了 2 个很好的答案。

        注意事项: “SELECT *”糟透了……只选择您需要的列。 Re0sless 在关键字之间放置了一个“或”。 - 你应该消除常用词(“”,“i”,“am”,“and”..etc) - mysql 对查询的大小有 8kb 的限制,因此对于非常长的 SELECTS,您应该将其放入单独的查询中。 - 尝试消除重复的关键字(如果我搜索“你知道你喜欢它”,则 SELECT 基本上应该只搜索一次“你”,并将常用词删除为“它”)

        还可以尝试使用“LIKE”和“MATCH LIKE”(参见 mysql 手册页)它可以为“模糊”搜索创造奇迹

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-27
          • 2017-06-02
          • 1970-01-01
          相关资源
          最近更新 更多