如何在不使用 Java 或 Google 网站搜索的情况下向 PHP 网站添加搜索功能


How to add a search functionality to a PHP website, without using Java or Google site search?

我想在我的网站上添加一个搜索字段。该网站基于 PHP 和 Yii 框架。Web服务器在提供生成的网页之前组装多个数据(来自文件和API)(Web服务器迟早会从MySQL数据库中获取这些数据,但目前只是文件和API结果)。

Apache的Lucene可以回答这个问题,但是没有办法在服务器上使用Java——我在共享的Linux主机上。

谷歌网站搜索(或必应,..)可以回答这个问题,但我希望有一个完全可定制的搜索框,并在建议的结果中添加一些结果。

我可以创建自己的搜索引擎,索引页面并根据每条数据的来源使用不同的权重,以获得精确的结果;但我认为一定有一些东西会更有效,更快地实现。

有什么

方法可以在不使用Java或Google网站搜索的情况下向基于PHP的网站添加快速搜索功能?

我使用Zend Framework,因此Zend_Search_Lucene。 它是分面搜索的纯 PHP 实现。 您可以相对直接地定义自己的"文档"(作为数据的聚合)、权重轴和构建索引。 根据我的经验,缺点是它在索引和查询方面比(例如)solr 慢得多。

更新 1作为对评论的回应,这里有一个链接:我如何使用Zend_Search_Lucene进行空间搜索。 那里的代码演示了一些事情:

  • 第 54-62 行显示了如何将"文档"添加到索引中。 在此示例中,文档只有两个字段(经度和纬度),但您明白了。 只需将其放在一个循环中,然后将文档添加到索引中即可。 在生产操作中,我跟踪数据的更改,并在进入索引文档的任何数据发生更改时更新索引。 最初的导入非常慢 - 根据经验,我发现算法至少是O(n log n)和一个相当大的K,而solr更像O(log n)。
  • 第 42-52 行显示如何搜索索引。 此搜索比平时复杂一些,因为我必须以与索引中的编码相同的方式对经度和纬度进行编码。 本文解释了为什么必须这样做,但足以说明:如果您只有文本数据,索引搜索并不难。
  • 第 40 行正在创建索引,前两个项目符号中提到的"添加"和"搜索"都需要索引。 请注意,将索引保持在快速介质(如 SD 存储)上会降低算法中的 K,但它仍然是(经验上,而不是分析上)O(n log n)。
  • 第 1-38 行是将经度和纬度规范化为 Zend_Search_Lucene 支持的格式所需的帮助程序。 同样,如果您只有文本数据,则不需要这种复杂性。

更新 2 回应有关性能的评论。 将索引放在快速介质上(SD,带同步的RAM磁盘等)可以加快速度。 使用未存储的字段也有帮助。 这两者都减少了经验O(n log n)中的常数,但主要问题仍然是n乘数。 Zend似乎所做的是,在每次添加时,重新洗牌大部分或全部先前添加到索引中。 据我所知,这是索引构建过程中使用的算法,无法修改。

我绕过 n 乘数的方法是使用基于词干查询的 Zend 页面缓存(因此,如果有人输入"蓝莓"、"蓝莓"、"蓝莓"、"蓝光"等,它们都会被词干化并固定在 soundex 语音"blue-bear-ee")。 常见查询几乎可以立即获得结果,并且由于特定域读取量大且插入潜伏,因此这是一个可接受的解决方案。 显然,一般来说不是。

在其他情况下,有setResultSetLimit()方法,当与评分一起使用时,将更快地返回结果。 如果你不关心所有可能的结果,只关心前N个结果,那么这就是你要走的路。

最后,所有这些经验都与 Zend 1.x 有关。 我不知道这是否已在 2.x 中得到解决。

有很多搜索引擎。就我个人而言,我喜欢狮身人面像搜索。但是您需要能够在您的(或远程)服务器上编译和运行它。您可以在基于php的搜索引擎上查找,例如seekquarry

您需要

将所有数据(页面名称和URL)保存在数据库中,然后才能在MySql查询中使用LIKE运算符进行搜索功能:

mysql_query("
SELECT *
FROM `table`
WHERE name LIKE '%keyword%'
")