问题
现在给出很多份文档,现在对某个搜索词感兴趣,想找到相关的文档。
简单搜索
一种简单粗暴的做法是:
1、读取每个文档;
2、找到其中含有搜索词的文档;
3、对找到的文档中搜索词出现的次数统计;
4、根据搜索词统计次数对文档按降序排序。
这称之为信息获取(Information Retrieval, IR),也叫简单搜索
普通IR方案存在的问题:
文档的体积增大或者数量增多,算法效率会下降
改进搜索的方案
Lucene项目对文档进行索引来快速搜索。
问题又来了:
仅有索引仍不够,还有:
链接分析(PageRank)
用户点击分析
自然语言处理
无链接文档的排序,
这些技术能增强搜索功能。
搜索的过程
通过爬虫从互联网中搜集数文档
用Lucene来分析、索引并搜索搜集的文档。
搜索的基本过程:加载、索引、搜索。
FetchAndProcessCrawler类
快速读取和存储网页的类FetchAndProcessCrawler(还可从互联网读取数据),
采集数据并解析,处理结果放在一个目录中。
每一组处理过的文档,都有四个相应的子目录:fetched、knownurls、pagelinks和processed。
分开了网页的元数据和核心内容,取出网页的链接(外链,outlink)。
LuceneIndexer类
LuceneIndexer类(对LuceneIndexBuilder的包装)
对以处理过的数据进行索引
Lucene用IndexWriter类创建索引,其构造函数的三个参数为:
1、存放索引的目录
2、所使用的分析器
3、布尔变量,决定是否覆盖已有的目录
爬去的文档是按组分类的:
第一组是初始URL的文档
第二组是第一组文档链接指向的文档
第三组是第二组中文档中链接所指向的文档
indexDocument方法索引每组中各个文档的内容,Lucene的类Document类封装了所采集的文档,
从而能将它们添加到索引中,这个类不仅能用来封装网页,还能将所以可以解析并能转换成纯文本的文档。
每一个Document类的实例都是一个由若干个域组成的虚拟文档。
用分解的方法处理所采集的文档,从而为每个文档创建若干个Field实例。
content域:文本文档的内容,删除了格式化标签和其他注释
url域:用于获取文件的URL
docid域:文档独一无二的标识符
title域:文件的标题
doctype域:文件的类型
每个文档的content域都会被索引,但是不会存放在索引文件中;
其他域都会存放在索引文件中,但不会被索引。
尽管是对文档内容进行查询,但是也需要从索引文件中获得文档的URL、ID和标题。
这中常用的做法在索引文件中只需存放一些能识别搜索结果的指针,如果没有特别的原因
(例如随时获得部分内容,而原始来源不能直接访问),不需要直接把内容放在索引文件中。
MySearcher类
MySearcher类搜索新建的索引
构造方法为索引所在目录。
使用search方法进行搜索,有两个参数:
需要在索引中查询的字符串;
想要获取的文档数量的上限。
search方法的步骤:
1、使用Lucene的IndexSearcher类的实例打开要搜索的索引;
2、创建一个Lucene的QueryParser类的实例,参数是要搜索的域和分析查询文本所必需的分词器;
3、用QueryParser的parse方法将人类语言查询转换成一个Lucene能理解的Query实例;
4、搜索索引,结果以Lucene的Hits对象的形式返回;
5、遍历前n个结果,放在SearchResult对象中。Lucene的Hits对象中只含有指向文档的引用。用这些引用收集所需的域;
6、记录每个文档的相关性分数,在0~1之间。