【问题标题】:keyword relevance PHP MySQL Search Engine关键字相关性 PHP MySQL 搜索引擎
【发布时间】:2012-10-30 23:28:06
【问题描述】:

我不知道为什么我在任何地方都找不到这个。我认为这将是非常普遍的要求。我正在用 PHP 编写一个搜索引擎,以在 MySQL 数据库中搜索用户输入的关键字。

表中有几列,但只有 2 列需要搜索。它们被命名为 file_Title 和 file_Desc。把它想象成一个分类广告。项目标题和描述。

例如,用户会搜索“John Deere Lawn Tractor”。我想要发生的是所有这 4 个词都显示在列表顶部的分类。然后结果只有 3 个,依此类推。

我在http://www.roscripts.com/PHP_search_engine-119.html阅读了一个非常好的网页

从该作者的示例中,我有以下代码:

<?php
    $search = 'John Deere Lawn Tractors';
    $keywords = split(' ', $search);

    $sql = "SELECT DISTINCT COUNT(*) As relevance, id, file_Title, file_Desc FROM Listings WHERE (";

    foreach ($keywords as $keyword) {
        echo 'Keyword is ' . $keyword . '<br />';
        $sql .= "(file_Title LIKE '%$keyword%' OR file_Desc LIKE '%$keyword%') OR ";
    }
    $sql=substr($sql,0,(strLen($sql)-3));//this will eat the last OR

    $sql .= ") GROUP BY id ORDER BY relevance DESC";
    echo 'SQL is ' . $sql;  

    $query = mysql_query($sql) or die(mysql_error());
    $Count = mysql_num_rows($query);
    if($Count != 0) {
                echo '<br />' . $Count . ' RESULTS FOUND';
        while ($row_sql = mysql_fetch_assoc($query)) {//echo out the results
            echo '<h3>'.$row_sql['file_Title'].'</h3><br /><p>'.$row_sql['file_Desc'].'</p>';
        }
    } else  {
        echo "No results to display";
    }

?>

输出的 SQL 字符串是这样的:

 SELECT DISTINCT COUNT(*) As relevance, id, file_Title, file_Desc FROM Listings 
  WHERE ((file_Title LIKE '%John%'
    OR file_Desc LIKE '%John%')
    OR (file_Title LIKE '%Deere%' 
    OR file_Desc LIKE '%Deere%') 
    OR (file_Title LIKE '%Lawn%' 
    OR file_Desc LIKE '%Lawn%') 
    OR (file_Title LIKE '%Tractors%' 
    OR file_Desc LIKE '%Tractors%') ) 
 GROUP BY id 
 ORDER BY relevance DESC

使用此代码,我可以从我的数据库中获得 275 个结果。我的问题是它真的不按行中找到的关键字数量排序。它似乎是按 id 排序结果。如果我删除 'GROUP BY id' 那么它只返回 1 个结果而不是所有结果,这真的让我很困惑!

我也尝试在数据库中切换到 FULLTEXT,但似乎也无法实现,所以我更愿意坚持使用 LIKE %Keyword% 语法。

感谢任何帮助!谢谢!

【问题讨论】:

  • 我强烈建议不要在数据库中做这么多的工作。您将很快陷入数据库并导致性能问题。数据库通常是导致可扩展性问题的堆栈的第一部分。
  • 我会从数据库中提取数据,然后修改输出以反映您的显示偏好。一旦数据在您的应用程序中,就更容易分辨出什么是什么。使其成为服务器端功能。在你的情况下这不可能吗?
  • 你应该使用全文搜索......

标签: php mysql search-engine


【解决方案1】:

我会建议一种完全不同的方法。您的方法繁琐、效率低下、对数据库的负担很大,并且随着越来越多的记录添加到您的数据库中,可能会非常缓慢。

我的建议如下:

  1. 为关键字创建单独的表格。
  2. 创建一个您不想索引的非关键字列表(如常见的英语介词等),这样它们就不会被包括在内。你 可能可以在网上找到他们的清单,随时可用。
  3. 添加新条目时,将字符串拆分为单独的关键字,省略步骤 2 中的关键字,然后将它们插入 在第 3 步中创建的表(如果尚未在其中)。
  4. 在一个单独的表中,使用指向关键字表的外键,将 classifed_ad 与关键字相关联。

如果您的分类广告被编辑(即从关联表中删除在第 4 步中插入的所有关键字,并且重新分析关键字并与分类广告重新关联),则必须再次执行第 3 步和第 4 步。

一旦你有了这个结构,你所要做的就是搜索关联表并按匹配关键字的数量排序。您甚至可以在其中添加一个额外的列,并将该关键字的出现次数放在文章中,这样您也可以按此排序。

这样会快很多。

我曾经使用过一个名为Sphider 的脚本,它做了类似的事情。不确定它是否仍在维护,但它在解析的网页上以非常相似的方式工作。

【讨论】:

    【解决方案2】:

    我知道你说你在使用 FULLTEXT 时遇到了问题,但我强烈建议你回去再试一次。 FULLTEXT 索引和搜索旨在做您正在做的事情,当在 WHERE 子句中使用 MATCH 命令时,MySQL 会自动将行从最高相关性到最低相关性进行排序。

    有关 FULLTEXT 的更多信息,请查看http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

    另外,请特别注意同一页上 Patrick O'Lone 的评论,其中一些引用如下...

    应该在文档中指出,IN BOOLEAN MODE 几乎总是会返回一个 1.0的相关性。为了获得相关性,即 有意义,您需要:

    选择匹配('内容')反对('keyword1 关键字 2') 作为表 WHERE MATCH 的相关性 ('内容') 反对('+keyword1 +keyword2' IN 布尔模式)相关性 > 0.2 阶 BY 相关性 DESC

    请注意,您正在执行常规相关性查询 获得与 WHERE 相结合的相关因子 使用 BOOLEAN MODE 的子句。布尔值 MODE 为您提供满足 布尔搜索的要求,相关性 查询满足相关因子,并且 HAVING 子句(在这种情况下)确保文件是 与搜索相关(即得分的文档 小于 0.2 被认为是不相关的)。这也是 允许您按相关性排序。

    【讨论】:

    • 谢谢!我必须让它工作。这是程序正在构建的查询字符串...SQL 是 SELECT DISTINCT MATCH(file_Title, file_Desc) Against ('John Deere Lawn Tractors' IN BOOLEAN MODE) 作为出现次数,id,file_Title,file_Desc FROM Listings WHERE ((file_Title LIKE ' %John%' OR file_Desc LIKE '%keyword%') OR(file_Title LIKE '%Deere%' OR file_Desc LIKE '%keyword%') OR(file_Title LIKE '%Lawn%' OR file_Desc LIKE '%keyword%') OR (file_Title LIKE '%Tractors%' OR file_Desc LIKE '%keyword%')) ORDER BY 出现次数 DESC .... 其他人说坏主意。不要让 db 完成工作。你的想法?
    • 查询的编写方式,它必须检查每一行。它没有使用 FULLTEXT 索引,因为 FULLTEXT 标准不在 WHERE 子句中(使用 MATCH / AGAINST)。你认为你的桌子会有多少行?一万?十万?百万?用量多少?您可以在 phpMyAdmin 中尝试各种查询,并了解每个查询需要多长时间。
    猜你喜欢
    • 2021-06-30
    • 2011-08-24
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    相关资源
    最近更新 更多