WebLucene 项目导读
一、Lucene因为WebLucene最基本的内核是Lucene,所以一个关键性的理解是在Lucene方面。
[url=http://lucene.apache.org/java/docs/images/lucene_green_300.gif]
对于lucene全文检索,可以简约地看看它的7个主要类,这7个类同时也表达了处理全文检索的7个意念。因为数据库比较为人所熟悉,它又与全文检索某些理念极为相似,所以在对下面的概念说明时,将会大量在渗入数据库和全文检索间的类比。
1)Document :它的中文意思是文档,对于一个文档,通常都包括它的标题、时间、作者、内容。如果让它的意思泛化,它也有文件的意思(相信Lucene的作者在取这个类名的时候也是经过再三斟酌的),对于文件,它可以指一个TXT文本、一个HTML网页、一个PDF文件等等。总而言之,它是映射着某一个具体的文件,这就是它的单位粒度。对应于数据库的概念是记录,英文是Record,weblucene在索引源的xml中就原原本本地采用了这个概念,可参照<weblucene_home>/dump/blog.xml 。
2)Field :中文意思是字段。汉语的翻译将这个单词的意思表达得更恰如其分了,意思是文字片段,它可以是一个或多个字。字段是文档(Document)的次粒度单位,也是检索的最基本单位。注意这个概念跟在搜索引擎的输入框中随意输入的那几个字或几组字不是一样的,在搜索输入框中输入的那些文字首先需要经过一个QueryParser(这也是7个类中的一个)将其分解成真正的Field。 在数据库中本来就有Field 这个概念,它即是Record的次级单位。在数据库一条或多条记录怎么被找出来的,往往就经由对Field的检索而得来。在全文检索中Document的最终取得也是差不多,它是根据现在的某个Filed来决定的。即根据文档中的某些还不完整的东西牵引出它的所需的全部。
示例代码:
[com.chedong.weblucene.search.WebLuceneResultSetTest]
Document doc = new Document();
doc.add(Field.Keyword("keyword", "房地产"));
doc.add(Field.Keyword("keyword", "非典"));
3)IndexWriter :索引书写者
示例代码:
[org.apache.lucene.index.TestIndexWriter]
Document doc = new Document();
doc.add(Field.UnStored("content", "aaa"));
try {
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true);
writer.addDocument(doc);
}
catch (IOException e) {
e.printStackTrace();
}
它的构造器new IndexWriter(dir, new WhitespaceAnalyzer(), true) 有三个参数,分别是Directory对象、分析器对象(这是下一个要介绍的类)和一个布尔量,是否要重写索引就是由这个布尔量标明的,如果取false则仅仅是将索引附加上来。
4)Analyzer : 分析器,它将目录中的一组原始文件分析成由一组Document和它相应的次级粒度Field组成的索引。因为不同的文件类型,同样的文本其内部文件流组织形式是不一样的,所以需要不同的分析器处理不同的文件类型(如PDFAnalyzer、HtmlAnalyzer)。又因为不同的文字语言处理Field拆分(Token)上是不一样的,所以在语言角度上又有另一层分析器的类别区分,如下面这行代码是处理普通中文字符的
[com.chedong.weblucene.search.WebLuceneResultSetTest]
IndexWriter writer = new IndexWriter(dir, new CJKAnalyzer(), true);
5)QueryParser :这前面在区分Field和用户输入的搜索关键字时已经提及了。(它所用的词是Query,跟数据库所用的是一个概念的,这个词同样的检索上让人感觉没有像Search那么费尽心思去深究。)QueryParser并没有实际地去做查询工作,它只是Parser(剖析)用户输入的东西,并把剖析的结果以一种规则的形式送给Searcher去执行一个真正的搜索。作为剖析的结果,不仅仅是Field,还有Field们相互间的关系(terms,譬如逻辑和AND,逻辑或OR, 逻辑非NOT)。
6)Searcher : 搜索一个Query,将结果返回。
[org.apache.lucene.search..TestNot]
RAMDirectory store = new RAMDirectory();
IndexWriter writer = new IndexWriter(store, new SimpleAnalyzer(), true);
Document d1 = new Document();
d1.add(Field.Text("field", "a b"));
writer.addDocument(d1);
writer.optimize();
writer.close();
Searcher searcher = new IndexSearcher(store);
Query query = QueryParser.parse("a NOT b", "field", new SimpleAnalyzer());
//System.out.println(query);
Hits hits = searcher.search(query);
对于每一个搜索器对象,它都需要指定一个索引文件路径,然后由搜索器对Query对象执行查询。 上面的这个类袖珍地对7个主要类都均有涉及。
7)Hits : Lucene的类注释是:A ranked list of documents, used to hold search results. 搜索的结果不仅仅是一些文档,而且这些文档还是有级别的,这个级别是对于先后次序而言的。它对应于数据库中的RecordSet / ResultSet 。
二、WebluceneWeblucene, 顾名思义,它即是基于web的lucene实现。
Weblucene是一个web全文检索的模块。
IndexRunner :根目录下的文件,按注释的说明是一个批量创建索引测试(batch indexing test)。注释说明如下
/**
* RUN: java IndexRunner [i:o:ah] <br>
* -i [input XML url] <br>
* -o [Output Dir] <br>
* -c [log4j config file] <br>
* -a append tag
*
* @param args
* command line arguments
*/
这种命令行参数的转换成接收能力是通过java-getopt.jar组件完成的。这个类的main()函数可以通过转换,将其改造成一个可供web事件触发的函数,用于创建或者追加索引。
SearchRunner :根目录下的文件,可以用于控制台搜索。
前台搜索入口的表单如下
<form action="search" method="get">
<input type="hidden" name="dir" value="comments">
<input type="text" size="40" name="q" value="中文">
<input type="hidden" name="start" value="0">
<input type="hidden" name="num" value="10">
<input type="hidden" name="index" value="FullIndex">
<input type="hidden" name="outputFormat" value="HTML">
<input type="hidden" name="encoding" value="UTF-8">
<input type="Submit">
<br>
<input type="radio" checked="true" value="DocID" name="orderStyle">按时间排序
<input type="radio" value="Score" name="orderStyle">按相关度排序
</form>
这个表单提交到search,即 com.chedong.weblucene.WebLuceneServlet 。
进入WebLuceneServlet为类
它的类介绍如下:
这个Servlet是搜索的接口,它所完成的任务是解析从request传过来的关键字,再到索引库中查找,然后返回一个经过xml转型的结果给客户端。
注意,这个搜索结果是xml格式,具体可参看/<weblucene-webapp>/weblucene_results.dtd。为了使结果展示成html和rss,我们使用了xslt模板,具体可参看/WEB-INF/var/blog/html.xsl。
搜索结果有三种显示模式,分别是html、xml、rss。
譬如在关键字框中输入[你好],搜索之后默认的显示页是html页,在地址栏上的url为http://z:8090/weblucene/search?dir=blog&q=%E4%BD%A0%E5%A5%BD&start=0&num=10&index=FullIndex&outputFormat=html&encoding=utf-8&orderStyle=DocID
^
将此处的outputFormat=html 中的html换成xml或rss,便可显示成相应的文件格式。
html文件中显示的我们已经看到的是一般正常的搜索结果,
xml 文件显示的完整的文档,该文档的显示格式可以参看<weblucene-webapp>\weblucene_results.dtd文件。
rss 文件现在文件显示上有点问题,它欠缺了扩展名xml,于是文件不被浏览器识别。
现在回过头来看它的索引文件的建立
在web.xml文件中有一个Servlet[com.chedong.weblucene.WebLuceneAdminServlet]被配置成<load-on-startup>1</load-on-startup>。即是它将在每次运行一个请求时都会被首先运行。这个Servlet只是重新加载了配置
IndexCreate.java,它可以接收源目录、索引文件存放的目录以及判断是否重建索引的标识。