zoukankan      html  css  js  c++  java
  • Lucene使用指南

     Lucene简介

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

    Lucene 是为文本类型的数据建立索引的,所以只要能把需要索引的数据格式转化的文本的,Lucene 就能对文档进行索引和搜索。比如HTML、PDF,都可以转换文本再交给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 类是一个抽象类,它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 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

    如果不乐意去了解诸如BooleanQuery,PhraseQuery等看上去复杂的查询类型。希望的是输入一个字符串,它就能够理解用户的搜索意图,然后转换成lucene中合理的Query子类,提供给lucene进行搜索,那这个就是QueryParser。QueryParser能够根据用户的输入来进行解析,自动构建合适的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;

        }

  • 相关阅读:
    从头认识java-17.4 具体解释同步(2)-具体解释竞争条件
    ProgressBar的indeterminateDrawable属性在安卓6.0上的问题
    Android开源-NineOldAndroids
    面向对象语言的多态性问题
    Android Data Binding代码实践(告别findViewById)(四)
    【c语言】将正数变成相应的负数,将负数变成相应的正数
    Android 消息处理源代码分析(2)
    怎样学习嵌入式软件
    C++ regex
    C++中两个类相互include的问题
  • 原文地址:https://www.cnblogs.com/yefengmeander/p/2887572.html
Copyright © 2011-2022 走看看