0

我不知道为什么我在任何地方都找不到这个。我认为这将是非常普遍的要求。我正在用 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%语法。

任何帮助表示赞赏!谢谢!

4

2 回答 2

2

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

我建议如下:

  1. 为关键字创建一个单独的表格。
  2. 创建一个您不想索引的非关键字列表(如常见的英语介词等),以便不包括在内。您可能可以在网上找到它们的列表,随时可用。
  3. 添加新条目时,您将字符串拆分为单独的关键字,省略步骤 2 中的关键字,并将它们插入在步骤 3 中创建的表中(如果还没有的话)。
  4. 在一个单独的表中,使用指向关键字表的外键,将 classifed_ad 与关键字相关联。

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

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

那会快得多。

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

于 2012-11-11T04:24:47.687 回答
0

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

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

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

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

SELECT MATCH('Content') AGAINST ('keyword1 keyword2') as Relevance FROM table WHERE MATCH ('Content') AGAINST('+keyword1 +keyword2' IN BOOLEAN MODE) HAVING Relevance > 0.2 ORDER BY Relevance DESC

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

于 2012-11-11T05:40:58.243 回答