对于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 。