补交欠着的作业,今天把 Lucene 和网站部分介绍一下。
基于之前的描述,假设我们已经完成了各个网站的文章抓取,那我们现在开始来做 Lucene 索引。
1、首先,我们将之前抓取后文档存储的数据库表 Documents 增加一个字段,叫“ LuceneIndexStatus ”,用来标记每一篇文章所需要等待操作。具体可以定义如下:0=不需要 Lucene 操作,1=等待添加,2=等待更新,3=等待删除。
2、写一个 Lucene 索引程序,可以是 Console 脚本,也可以是 exe 程序,都无所谓。程序通过搜索 Documents 表待操作的文档,将其添加 /更新 /删除到 Lucene 索引。我使用的 Lucene 版本没有更新功能,所以得先删除后添加。
3、词库和分词:lucene 索引和查询要使用同一个分词系统和词库。关于词库网上的也不一定全,需要自己补充词库 ,我把地域、学校、城市、街道、小区、名人名字等添加到词库,另外写一个新词发现系统,用来生成新词自动添加到词库。新词发现系统的逻辑,就是运算大量的正文,基于标点符号和停用词分段后,如果几个字的排列组合还大量出现,则认定为新词。
4、添加 Lucene Document 时候的 Trick:
a )关于 Lucene.Net.Documents.Field.Store。为了前台检索性能考虑,将 Title、Description、URL 等关键字段设置成需要存储,这样当前台用户执行搜索时,执行了 Lucene 搜索后就能够直接获得这些信息,就不用再去数据库基于 ID 查匹配的 Title、Description 等信息了。这种做法,虽然 Lucene 索引做完后空间大了一点,但是查询性能会更好,毕竟减少了数据库 io。其他的一些辅助字段譬如 hostname (为了支持 insite 命令),就不需要存储了。
b )建立 URL、Hostname 两个 Lucene 字段,而且设置成需要分词。URL 的目的是支持 inurl,hostname 的目的是支持 insite。在查询的时候可以查询 url 和 hostname,并给以一定的权重,譬如搜索 hadoop 的时候,hostname 为
hadoop.org 的文章会获得更高的权重。
c) 在文章入 Lucene 库前,可以计算并设置一下文档的 boost 值,LuceneDocument.SetBoost(BoostValue)。计算文章 Boost 值可以基于:文章内容和标题的质量、详尽程度、网站权重、文章类型(博客、教程、还是新闻)等方法。建议在计算 boost 值时可以考虑使用 math.log10 函数,以较好的控制极大极小值,让 boost 值落在自己需要的区间。
5、Lucene 索引完成后一定要 optimize,个人感觉最好 optimize 三次才有比较好的性能。
6、要把 Lucene 操作 Index 的库和前台搜索的库分开,每次后台完成 Lucene 库 index 更新和 optimize 后,自动 copy 到前台的查询库,然后通知前台网站更换查询的 lucene 库。
7、Lucene 库一旦 optimize 完成后,前台搜索不要更改这个库,否则产生碎片会影响查询性能。正确做法是,前台搜索指向两个或者多个 lucene 库。一个大库是定期更新的,可能有几百 G,由索引程序生成。还有若干个小库,是前台实时添加文档到索引,以支持查询使用的。前台 lucene 搜索时,搜索的是几个库的并集。