如何使用PHP和MySQL实现简单的网站搜索?

15

我正在创建一个网站,允许用户提交引用语。如何创建一个(相对简单的)搜索功能,以返回最相关的引用语?

例如,如果搜索词是“turkey”,那么我将返回出现两次“turkey”单词的引用语,然后是仅出现一次的引用语。

(我会添加一些其他规则来帮助过滤掉不相关的结果,但我的主要关注点是这个。)


1
说实话,SQL(任何变体)在这种情况下并不是很擅长。 - cletus
10个回答

34

大家都建议使用MySQL全文搜索,但是你应该知道一个巨大的警告。全文搜索引擎仅适用于MyISAM引擎(不适用于InnoDB引擎,后者是由于其参照完整性和ACID兼容性而被广泛使用)。

所以你有几个选择:

1. 最简单的方法是由Particle Tree概述。您实际上可以通过纯SQL(没有全文搜索或其他东西)获得排名搜索。以下SQL查询将搜索表格并根据搜索字段中字符串出现次数对结果进行排名:

SELECT
    SUM(((LENGTH(p.body) - LENGTH(REPLACE(p.body, 'term', '')))/4) +
        ((LENGTH(p.body) - LENGTH(REPLACE(p.body, 'search', '')))/6))
    AS Occurrences
FROM
    posts AS p
GROUP BY
    p.id
ORDER BY
    Occurrences DESC

编辑他们的示例以提供更多的清晰度

对上述SQL查询进行变体,添加WHERE语句(WHERE p.body LIKE '%whatever%you%want'),等等,可能会让您得到所需的结果。

2. 您可以更改数据库架构以支持全文检索。通常所做的是将引用完整性、ACID兼容性和速度保持在不必安装像Sphinx Fulltext Search Engine这样的MySQL插件的前提下,将引用数据拆分为自己的表格。基本上,您将拥有一个名为Quotes的InnoDB表,它不再具有您的TEXT字段"data",而是具有指向Quote_Data表上的ID的引用"quote_data_id",该表是一个MyISAM表。您可以在MyISAM表上执行全文搜索,将返回的ID与InnoDB表连接起来,然后就可以获得结果了。

3. 安装Sphinx。祝您好运。

考虑到您所描述的情况,我强烈建议采用我提出的第一种方法,因为您拥有一个简单的数据库驱动站点。第一种解决方案简单易行,快速解决问题。Lucene将是一个麻烦的设置,特别是如果您想将其与数据库集成,因为Lucene主要设计用于索引文件而不是数据库。Google自定义网站搜索只会让您的网站失去大量声誉(使您看起来业余和不专业),而MySQL全文检索很可能会导致您更改数据库架构。


2
选项1很有趣!以前从未见过。由于查询的复杂性,对实时数据进行基准测试是必不可少的,但如果您拥有小型数据集,则可以成为Sphinx/MyISAM的不错替代品。 - James Brady
2
从MySQL 5.6开始,InnoDB也支持全文搜索。 - Marcus Adams

6

3
我愿意自己制作。每个报价不会独占一页,所以我认为谷歌并不是很适用。 - stalepretzel

3

Stackoverflow 计划使用 Lucene 搜索引擎。这是一个为 Zend Framework 编写的 PHP 移植版本,但可以作为独立实体下载,无需所有的 ZF 冗余。这被称为 Zend_Search_Lucene,其文档可以在此处找到


我有一个疑问@DavidM:我有用HTML和PHP创建的网页..那么,我可以使用Lucene搜索引擎在我的网页中搜索任何单词吗?谢谢 - pcs

2
你要查找包含“turkey”的引用的 SQL 查询语句大致如下:
SELECT * FROM Quotes
WHERE the_quote LIKE "%turkeyt%";

从那里,你可以弄清楚如何处理它向你输出的任何内容。
要小心处理恶意用户可能会向你的数据库注入恶意SQL的情况,特别是如果你计划将其放在互联网上。不过,如果你只是出于兴趣而做这个项目,那么就看你想学习什么了。
如果你是数据库和 SQL 的新手,我建议你使用 SQLite 而不是 MySQL。它更容易设置和使用,因为无需安装设置。这将避免你第一次安装和设置 MySQL 时可能遇到的潜在问题。SQLite

这并不会给你一个排名(例如,排名是火鸡出现次数的数量)。 - dcousineau
等等,什么?你的意思是我应该小心SQL注入?不可能吧! :) 我本来想采用你描述的方法,但我认为将其转化为排名系统并不容易。 - stalepretzel
只是不确定你的技能水平。如果你想要一个简单的排名系统,可以让用户为引用创建标签并搜索标签。由于引用不是很大的文本体,你可能需要分析名词/动词来确定排名。或者仅仅计算一个词汇的出现次数即可。 - Jeffrey Martinez
我不完全理解“引号标签”的评论,但是建议不要在已经有这么多现成且强大的选项时再去拼凑出类似于此的东西。包括 MySQL 在内,都有很多内置的选项可供选择... - James Brady

1

1
如果你想要编写自己的搜索引擎,可以看看phpBB的实现方式。他们使用了两个表格,第一个表格是所有出现在条目中的单词的唯一列表,第二个表格是单词和条目之间的多对多关系引用。然后,你可以进行分组和计数以按照你想要的方式对条目进行排序。
这比实现第三方搜索引擎(或全文搜索)要复杂得多,但它将允许你更好地控制结果。

1
作为 Sphinx 和 Lucene 的替代方案,可以使用 Xapian 库创建一个相对简单的搜索引擎。 + 支持许多高级搜索功能(如相关性排名)
+ 快速 - 您需要学习 API 来创建您的接口
- 需要安装 PHP 扩展
请注意,Xapian 将其数据存储在与 MySQL 不同的索引中。
您可能还会对 Forage 感兴趣,它是 Solr、Xapian 和 Lucene 的包装器。
Xapian 的开发人员还创建了 Omega 搜索引擎,它是 Xapian 的前端,并可以通过 CGI 调用。

1

0

几天前我发现了Zoom Search Engine,我认为这可能是我使用过的最简单的搜索引擎。

这个基于Windows的工具创建了一个站点的数据库,然后它还会询问您想要使用哪种语言(PHP、ASP.NET、JavaScript等)。我选择了PHP,它为我构建了PHP代码。然后,我所需要做的就是将文件上传到服务器上,(可选)自定义模板,站点搜索就可以工作了。

对于小型网站来说,这是免费的,唯一的缺点是蜘蛛工具(数据库构建器)必须在Windows上运行。


0

谷歌自定义站点搜索很好,如果您不经常查询它(我认为您可以免费获得每天1k个查询),或者您愿意付费。

MySQL的全文搜索也是一个很好的资源(正如以前提到的那样)。

雅虎的BOSS是一个有趣的项目 - 我将在我的下一个搜索项目中尝试它。

最后,Lucene是一个很好的资源,如果您需要比全文搜索更强大的功能,但想要调整自己的搜索引擎。http://lucene.apache.org


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接