Lucene使用指南

 

 

Lucene使用指南

 

 Lucene简介

Lucene是一个基于Java的、高性能的全文检索工具包,它目前是著名的 Apache Jakarta 家族中的一个开源项目,也是目前最为流行的基于 Java 开源全文检索工具包。但它不是一个完整的搜索应用程序,而是为应用程序提供索引和搜索功能。

 

Lucene 是为文本类型的数据建立索引的,所以只要能把需要索引的数据格式转化的文本的,Lucene 就能对文档进行索引和搜索。比如HTMLPDF,都可以转换文本再交给Lucene进行索引。

1. Lucene环境

 1.1 Lucene版本

当前版本:取当前最新版本Lucene Core 3.4.0

下载地址:http://lucene.apache.org/java/docs/index.html

linux版本: lucene-3.4.0.tgz

windows版本:lucene-3.4.0.zip

 

 1.2 IKAnalyzer中文分词器

Lucene的分词器以接口Analyzer的形式对外提供,外部根据业务需要实现该分词器。Lucene本身提供了标准分词器StandarAnalyzer,针对英文的分词。

 

中文分词器现在比较成熟的是开源项目的IKAnalyzer,是针对中文的分词, 目前最新版本是IKAnalyzer3.2.8.jar

下载地址http://code.google.com/p/ik-analyzer/downloads/list

 

2. Lucene和应用程序的关系

 


 

 

 

3. Lucene API使用

 

 3.1 建立索引

为了对文档进行索引,Lucene 提供了五个基础的类,他们分别是 Document, Field, IndexWriter, Analyzer, Directory。下面我们分别介绍一下这五个类的用途:

 

Document

Document 是用来描述文档的,这里的文档可以指一个 HTML 页面,一封电子邮件,或者是一个文本文件。一个 Document对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录的一个字段。

Field

Field 对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。

Analyzer

在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类,它有多个实现。针对不同的语言和应用需要选择适合的 AnalyzerAnalyzer 把分词后的内容交给 IndexWriter 来建立索引。

IndexWriter

IndexWriter  Lucene 用来创建索引的一个核心的类,他的作用是把一个个的 Document 对象加到索引中来。

Directory

这个类代表了 Lucene 的索引的存储的位置,这是一个抽象类,它目前有两个实现,第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。

 

使用例子

 

public void createIndexs() throws Exception

{

    String indexDir = "d:\\Temp\\lucence\\indexDir";

    String dataDir = "d:\\Temp\\lucence\\dataDir";

    Analyzer  analyzer = new IKAnalyzer(true); // 使用中文分词器

    File dir = new File(dataDir);

    File[] files = dir.listFiles();

   

    Directory fsDirectory = FSDirectory.open(new File(indexDir));

    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_34, analyzer);

    config.setOpenMode(OpenMode.CREATE_OR_APPEND);

    config.setMaxBufferedDocs(1000);

    IndexWriter indexWriter = new IndexWriter(fsDirectory, config);

   

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

{

         String filePath = files[i].getAbsolutePath();

        

         if(filePath.endsWith(".html") || filePath.endsWith(".htm"))

        {

             HTMLDocParser htmlParser = new HTMLDocParser(filePath);

              String path    = htmlParser.getPath();

              String title   = htmlParser.getTitle();

              Reader content = htmlParser.getContent();

             

              Document document = new Document();

            document.add(new Field("path", path, Field.Store.YES,

                        Field.Index.NO, Field.TermVector.NO));

            document.add(new Field("title", title, Field.Store.YES,

                        Field.Index.ANALYZED,

                        Field.TermVector.WITH_POSITIONS_OFFSETS));

            document.add(new Field("content", content,

                        Field.TermVector.WITH_POSITIONS_OFFSETS));

        

              indexWriter.addDocument(document);

        }

    }

    indexWriter.commit();

    indexWriter.optimize();

    indexWriter.close();

}

 


 3.2 搜索文档

在上面一部分中,我们已经为一个目录下的文本文档建立好了索引,现在在这个索引上进行搜索以找到包含某个关键词或短语的文档。Lucene 提供了几个基础的类来完成这个过程,它们分别是呢 IndexSearcher, Query, QueryParser,TopDocs下面我们分别介绍这几个类的功能。

 

Query

这是一个抽象类,Lucene针对不同的类型提供了不同的实现,比如 TermQuery, BooleanQuery, PrefixQuery,PhraseQuery这个类的目的是把用户输入的查询字符串封装成 Lucene 能够识别的 Query

QueryParser

如果不乐意去了解诸如BooleanQueryPhraseQuery看上去复杂的查询类型。希望的是输入一个字符串,它就能够理解用户的搜索意图,然后转换成lucene中合理的Query子类,提供给lucene进行搜索,那这个就是QueryParserQueryParser能够根据用户的输入来进行解析,自动构建合适的Query对象。

IndexSearcher

IndexSearcher 是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引,所以可以有多个 IndexSearcher的实例在一个索引上进行操作。

TopDocs

TopDocs是用来保存搜索的结果。保存前N条得分高的记录。

 

使用例子

 

    public List search(String strQuery) throws Exception

    {

        List searchResult = new ArrayList();

        String indexDir = "d:\\Temp\\lucence\\indexDir";

        String field = "content";

         Analyzer  analyzer = new IKAnalyzer(true); // 使用中文分词器

        

         Directory fsDirectory = FSDirectory.open(new File(indexDir));

        IndexSearcher indexSearcher = new IndexSearcher(fsDirectory, true);

 

        QueryParser queryParser = new QueryParser(Version.LUCENE_34, field, analyzer);

        Query query = queryParser.parse(strQuery);

       

        if (null != query && null != indexSearcher)

        {

            TopDocs hits = indexSearcher.search(query, 1000);

            int totalHits = hits.totalHits;

            int len = Math.min(1000, totalHits);

 

            ScoreDoc[] docs = hits.scoreDocs;

            for (int i = 0; i < len; i++)

            {

                SearchResultBean resultBean = new SearchResultBean();

 

                Document doc = indexSearcher.doc(docs[i].doc);

                resultBean.setHtmlPath(doc.get("path"));

                resultBean.setHtmlTitle(doc.get("title"));

                searchResult.add(resultBean);

            }

        }

        return searchResult;

    }

 

 

4. 附录

 

提供一个简单的Lucene Demo工程。参考lucene-demo.rar

 

 

猜你喜欢

转载自jony-hwong.iteye.com/blog/1292263