【问题标题】:Advanced search functionality高级搜索功能
【发布时间】:2010-05-03 19:57:01
【问题描述】:

我有一个基于 jQuery 的自动完成搜索功能的网站,效果很好。

目前虽然我只有一个搜索框可以搜索所有类别,但我希望有人能够输入,例如 dorian gray dvd(以任何顺序),它将在 @ 中搜索 dorian gray 987654323@ 类别。那么这需要在服务器端使用一点魔法来确定是否有任何单词是类别关键字,然后以此来限制搜索。

在 PHP / MySQL 中最好(和最快)的方法是什么?

我目前有一些思路

  • 搜索类别 匹配表和订单 结果。
  • 或将搜索词拆分为 数组并分别搜索 匹配的类别。
  • 我刚刚想到的另一个想法是 将类别标题连接到 DVD 数据库中的标题和匹配 反对,或类似的东西...... 但这听起来在计算上 贵吗?

有什么建议吗?

【问题讨论】:

    标签: php mysql search


    【解决方案1】:

    就循环和代码行而言,您的第一个想法可能是最快的。展开搜索查询,包装新数组的每个部分以对其进行格式化,以便您可以将其内爆并将新字符串附加到 mysql 查询的末尾。

    然后只需获取结果并将其附加到搜索查询中。为了节省空间,将搜索查询与类别查询同时格式化。

    $temp=explode(" ", $string);
    foreach($temp as $key=>$var) {
       $where[$key]=>"category='".mysql_real_escape_string($var)."'";
       $where2[$var]=>"field like '%".mysql_real_escape_string($var)."%'"; //formating the second query at the same time
    }
    $result=mysql_query("SELECT name FROM categories WHERE ".implode(" OR ", $where));
    $cat=mysql_fetch_object($result)->name;
    unset($where2['cat']); //removing the category from the search
    $where2=implode(" OR ", $where2);
    $result=mysql_query("SELECT * FROM table WHERE ($where2) and category='$cat'");
    

    【讨论】:

    • 你可能想用 mysql_real_escape_string() 进行转义。如果有多个关键字,您的第一个查询也会出现语法错误。
    • 我总是在您访问执行此类工作的实际文件之前清理我的一个包含中的任何用户输入。不管你是对的,我已经包含了 escape 并且应该有一个 OR 而不是 a ,谢谢。
    • 如果类别名称中包含单引号,它仍然会中断。我只是很挑剔不是吗
    【解决方案2】:

    IN() 在这里派上用场。有几种方法,它们的复杂性和性能各不相同 我假设您有一个类别表,并且无论使用该类别的任何内容都通过类别标识符使用它,如下所示:

    categories
        id
        name
    
    posts
        id
        category
        name
    

    此功能还删除与类别匹配的关键字 - 正如您所描述的。它还允许您搜索多个类别。尽管我不鼓励使用 LIKE "%keyword%" 因为它确实会影响性能,但它让您的搜索实现由您决定。

    使用 IN 关键字

    $keywords = $escaped_keywords = explode(' ', $user_input);
    array_walk($escaped_keywords, 'db_escape');
    $query = 'SELECT id, name FROM categories WHERE name IN ("' . implode('", "', $escaped_keywords) . ")";
    $result = db_query($query);
    $category_in = '';
    while($row = db_fetch($result)) {
        $category_in .= ($category ? ', ' : '') . db_escape($row['id']);
        unset($keywords[$row['name']))
    }
    if($category_in) {
        // $where is your conditional from your current script
        $where .= ($where ? ' AND ' : '') . "category IN($category_in)";
    }
    

    改为建立搜索索引

    另一种解决方案要复杂得多,因为它需要建立搜索索引。搜索索引将允许您在搜索索引的一部分中插入类别名称并将它们标记为与该关键字更相关(比在帖子正文中说的),并将类别标记为比其他关键字更相关。这样做的好处是您可以对首先出现的内容进行各种控制:例如:

    SELECT p.*, MAX(pi.relevance) relevance FROM posts LEFT JOIN post_index pi ON pi.post = post.id WHERE keyword IN (keyword_list) GROUP BY pi.post_date, pi.post ORDER BY relevance DESC
    

    您的索引器可以随心所欲地确定排序或相关性。困难的部分是确定何时为您的内容编制索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多