edfward

基于 Sphinx/Coreseek 的全文检索引擎

知乎日报的文章向来质量很高,遗憾的是不像知乎本身可以进行内容的搜索。恰好在和另一个朋友捣鼓微信公众账号,自然就想到利用后台的全文检索来实现这个功能。

用 PHP 和 Coreseek (一款基于Sphinx并支持中文的开源检索引擎) 实现最后的效果如图:

对不起静态图都挂了哇哈哈

下面来说一下实现步骤顺便也备忘一下。

Step 1: DATA

第一步当然是利用知乎日报提供的 api 提取数据并放入数据库中。

跑完这个脚本之后就算是拿到了原始数据,以后每天再做增量更新就行。

Step 2: INDEXING

全文检索最重要的部分当然就是检索引擎了。Lucene 的大名很早就听说过,但是最终还是选择了比较适合 PHP 的 Sphinx/Coreseek 来做中文索引。Stackoverflow 有篇很赞的比较文章,以及来自这篇 blog 的一副图:

sphinx

初次进行配置还是比较麻烦…其实也没什么好说的,多看看文档和一些快速教程基本就能摸清流程了。首先要了解 indexing 的工作流程 (如果数据源是 SQL 的话)

With all the SQL drivers, indexing generally works as follows.

  • connection to the database is established;
  • pre-query is executed to perform any necessary initial setup, such as setting per-connection encoding with MySQL;
  • main query is executed and the rows it returns are indexed;
  • post-query is executed to perform any necessary cleanup;
  • connection to the database is closed;
  • indexer does the sorting phase (to be pedantic, index-type specific post-processing);
  • connection to the database is established again;
  • post-index query is executed to perform any necessary final cleanup;
  • connection to the database is closed again.

然后记录一下配置过程方便以后进行类似的配置:

老实说其他就没怎么设置了…有空看看文档发现有用的再来补充 ;-)

配置好后通过 indexer 来建立索引, searchd 来开启 daemon 供 api 使用。关于这几个命令行工具(还包括 search, 但一般用 api 就行了不常用它)的参数除了文档还可以看这篇文章有比较详细的介绍。最常用的几个命令就是

Step 3: API

之后就是调用 api 了。重要的东西都在文档里的 Chapter 8 - API reference 里,在我们的应用里是这样调用的:

最后的事情当然就是设定一个凌晨的 crontab 把前一天的文章数据插入数据库然后重新索引一遍(现在重新索引大概只需要1秒左右所以增量索引应该还用不上)。

大致上这个功能的雏形就有了 ;-)

后记

其实这次捣鼓来捣鼓去还是个工程问题,能添加上这个功能固然是好,但是究其底细我对 information retrieval 这个领域基本上还是个小白,希望下次能写写这些开源引擎里的 ranking, sorting 用了什么算法,具体又是怎样实现的,我想帮助会更大。