随笔-72  评论-63  文章-0  trackbacks-0

今天用了下Lucene,发现网上虽然也有不少介绍它的文档,不过很多都偏向介绍概念呀、设计或者是一些更为深入的东西,对于其入门使用的介绍性的文档并不多,就写了这么一篇。

Lucene 基本使用介绍

 

本文的目的不在于对 Lucene 的概念和设计这些进行介绍,仅在于介绍怎么样去使用 Lucene 来达到自己想要的几种常见的全文检索的需求,如果想深入了解 Lucene 的话本文不会带给你什么收获的。看完本文后想更深入的了解 Lucene 请访问:http:// lucene.apache.org

 

一.  概述

随着系统信息的越来越多,怎么样从这些信息海洋中捞起自己想要的那一根针就变得非常重要了,全文检索是通常用于解决此类问题的方案,而 Lucene 则为实现全文检索的工具,任何应用都可通过嵌入它来实现全文检索。

二.  环境搭建

lucene.apache.org 上下载最新版本的 lucene.jar ,将此 jar 作为项目的 build path ,那么在项目中就可以直接使用 lucene 了。

三.  使用说明

3.1.       基本概念

这里介绍的主要为在使用中经常碰到一些概念,以大家都比较熟悉的数据库来进行类比的讲解,使用 Lucene 进行全文检索的过程有点类似数据库的这个过程, table--- à 查询相应的字段或查询条件 ---- à 返回相应的记录,首先是 IndexWriter ,通过它建立相应的索引表,相当于数据库中的 table ,在构建此索引表时需指定的为该索引表采用何种方式进行构建,也就是说对于其中的记录的字段以什么方式来进行格式的划分,这个在 Lucene 中称为 Analyzer Lucene 提供了几种环境下使用的 Analyzer SimpleAnalyzer StandardAnalyzer GermanAnalyzer 等,其中 StandardAnalyzer 是经常使用的,因为它提供了对于中文的支持,在表建好后我们就需要往里面插入用于索引的记录,在 Lucene 中这个称为 Document ,有点类似数据库中 table 的一行记录,记录中的字段的添加方法,在 Lucene 中称为 Field ,这个和数据库中基本一样,对于 Field Lucene 分为可被索引的,可切分的,不可被切分的,不可被索引的几种组合类型,通过这几个元素基本上就可以建立起索引了。在查询时经常碰到的为另外几个概念,首先是 Query Lucene 提供了几种经常可以用到的 Query TermQuery MultiTermQuery BooleanQuery WildcardQuery PhraseQuery PrefixQuery PhrasePrefixQuery FuzzyQuery RangeQuery SpanQuery Query 其实也就是指对于需要查询的字段采用什么样的方式进行查询,如模糊查询、语义查询、短语查询、范围查询、组合查询等,还有就是 QueryParser QueryParser 可用于创建不同的 Query ,还有一个 MultiFieldQueryParser 支持对于多个字段进行同一关键字的查询, IndexSearcher 概念指的为需要对何目录下的索引文件进行何种方式的分析的查询,有点象对数据库的哪种索引表进行查询并按一定方式进行记录中字段的分解查询的概念,通过 IndexSearcher 以及 Query 即可查询出需要的结果, Lucene 返回的为 Hits . 通过遍历 Hits 可获取返回的结果的 Document ,通过 Document 则可获取 Field 中的相关信息了。

通过对于上面在建立索引和全文检索的基本概念的介绍希望能让你对 Lucene 建立一定的了解。

3.2.       全文检索需求的实现

索引建立部分的代码:

private   void  createIndex(String indexFilePath) throws Exception {

        IndexWriter iwriter
= getWriter(indexFilePath);

        Document doc
= new  Document();

        doc.add(Field.Keyword(
" name " , " jerry " ));

        doc.add(Field.Text(
" sender " , " bluedavy@gmail.com " ));

        doc.add(Field.Text(
" receiver " , " google@gmail.com " ));

        doc.add(Field.Text(
" title " , " 用于索引的标题 " ));

        doc.add(Field.UnIndexed(
" content " , " 不建立索引的内容 " ));

        Document doc2
= new  Document();

        doc2.add(Field.Keyword(
" name " , " jerry.lin " ));

        doc2.add(Field.Text(
" sender " , " bluedavy@hotmail.com " ));

        doc2.add(Field.Text(
" receiver " , " msn@hotmail.com " ));

        doc2.add(Field.Text(
" title " , " 用于索引的第二个标题 " ));

        doc2.add(Field.Text(
" content " , " 建立索引的内容 " ));

        iwriter.addDocument(doc);

        iwriter.addDocument(doc2);

        iwriter.optimize();

        iwriter.close();

    }


    

    
private  IndexWriter getWriter(String indexFilePath) throws Exception {

        boolean append
= true ;

        File file
= new  File(indexFilePath + File.separator + " segments " );

        
if (file.exists())

            append
= false

        
return   new  IndexWriter(indexFilePath,analyzer,append);

    }


3.2.1.       对于某字段的关键字的模糊查询

Query query = new  WildcardQuery( new  Term( " sender " , " *davy* " ));

        

        Searcher searcher
= new  IndexSearcher(indexFilePath);

        Hits hits
= searcher.search(query);

        
for  ( int  i  =   0 ; i  <  hits.length(); i ++ {

            System.
out .println(hits.doc(i). get ( " name " ));

        }


3.2.2.       对于某字段的关键字的语义查询

Query query = QueryParser.parse( " 索引 " , " title " ,analyzer);

        

        Searcher searcher
= new  IndexSearcher(indexFilePath);

        Hits hits
= searcher.search(query);

        
for  ( int  i  =   0 ; i  <  hits.length(); i ++ {

            System.
out .println(hits.doc(i). get ( " name " ));

        }


3.2.3.       对于多字段的关键字的查询

Query query = MultiFieldQueryParser.parse( " 索引 " , new  String[] { " title " , " content " } ,analyzer);

        

        Searcher searcher
= new  IndexSearcher(indexFilePath);

        Hits hits
= searcher.search(query);

        
for  ( int  i  =   0 ; i  <  hits.length(); i ++ {

            System.
out .println(hits.doc(i). get ( " name " ));

        }


3.2.4.       复合查询(多种查询条件的综合查询)

Query query = MultiFieldQueryParser.parse( " 索引 " , new  String[] { " title " , " content " } ,analyzer);

        Query mquery
= new  WildcardQuery( new  Term( " sender " , " bluedavy* " ));

        TermQuery tquery
= new  TermQuery( new  Term( " name " , " jerry " ));

        

        BooleanQuery bquery
= new  BooleanQuery();

        bquery.add(query,
true , false );

        bquery.add(mquery,
true , false );

        bquery.add(tquery,
true , false );

        

        Searcher searcher
= new  IndexSearcher(indexFilePath);

        Hits hits
= searcher.search(bquery);

        
for  ( int  i  =   0 ; i  <  hits.length(); i ++ {

            System.
out .println(hits.doc(i). get ( " name " ));

        }


四.  总结

相信大家通过上面的说明能知道 Lucene 的一个基本的使用方法,在全文检索时建议大家先采用语义时的搜索,先搜索出有意义的内容,之后再进行模糊之类的搜索, ^_^ ,这个还是需要根据搜索的需求才能定了, Lucene 还提供了很多其他更好用的方法,这个就等待大家在使用的过程中自己去进一步的摸索了,比如对于 Lucene 本身提供的 Query 的更熟练的掌握,对于 Filter Sorter 的使用,自己扩展实现 Analyzer ,自己实现 Query 等等,甚至可以去了解一些关于搜索引擎的技术 ( 切词、索引排序 etc) 等等。

posted on 2006-05-06 01:52 船长 阅读(200) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: