`
csbison
  • 浏览: 153572 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Lucene 基础指南[转]

阅读更多

Lucene 基础指南

作者:lighter, 江南白衣

    Luceneapache组织的一个用java实现全文搜索引擎的开源项目。其功能非常的强大,但api其实很简单的,它最主要就是做两件事:建立索引和进行搜索。

1. 建立索引时最重要的几个术语

  • Document:一个要进行索引的单元,相当于数据库的一行纪录,任何想要被索引的数据,都必须转化为Document对象存放。
  • FieldDocument中的一个字段,相当于数据库中的Column Fieldlucene比较多概念一个术语,详细见后。
  • IndexWriter:负责将Document写入索引文件。通常情况下,IndexWriter的构造函数包括了以下3个参数:索引存放的路径,分析器和是否重新创建索引。特别注意的一点,当IndexWriter执行完addDocument方法后,一定要记得调用自身的close方法来关闭它。只有在调用了close方法后,索引器才会将存放在内在中的所有内容写入磁盘并关闭输出流。
  • Analyzer:分析器,主要用于文本分词。常用的有StandardAnalyzer分析器,StopAnalyzer分析器,WhitespaceAnalyzer分析器等。
  • Directory:索引存放的位置。lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地lucene提供了FSDirectoryRAMDirectory两个类。
  • 段:Segment,Lucene索引文件的最基本的一个单位。Lucene说到底就是不断加入新的Segment,然后按一定的规则算法合并不同的Segment以合成新的Segment

       lucene建立索引的过程就是将待索引的对象转化为LuceneDocument对象,使用IndexWriter将其写入lucene 自定义格式的索引文件中。

       待索引的对象可以来自文件、数据库等任意途径,用户自行编码遍历目录读取文件或者查询数据库表取得ResultSetLuceneAPI只负责和字符串打交道。

1.1 Field 的解释

从源代码中,可以看出Field 构造函数如下:

Field(String name, byte[] value, Field.Store store)

Field(String name, Reader reader)

Field(String name, Reader reader, Field.TermVector termVector)

Field(String name, String value, Field.Store store, Field.Index index)

Field(String name, String value, Field.Store store, Field.Index index, Field.TermVector termVector)

Field当中有三个内部类:Field.Index,Field.Store,Field.termVector。其中

  • Field.Index有四个属性,分别是:
    Field.Index.TOKENIZED
    :分词索引
    Field.Index.UN_TOKENIZED
    :不进行分词,如作者名,日期等,Rod Johnson本身为一单词,不再需要分词。
    Field.Index.NO
    :不进行索引,存放不能被搜索的内容如文档的一些附加属性如文档类型, URL等。
    Field.Index.NO_NORMS
    Index the field's value without an Analyzer, and disable the storing of norms. No norms means that index-time boosting and field length normalization will be disabled. The benefit is less memory usage as norms take up one byte per indexed field for every document in the index. Note that once you index a given field with norms enabled, disabling norms will have no effect. In other words, for NO_NORMS to have the above described effect on a field, all instances of that field must be indexed with NO_NORMS from the beginning.
  • Field.Store也有三个属性,分别是:
    Field.Store.YES
    :索引文件本来只存储索引数据, 此设计将原文内容直接也存储在索引文件中,如文档的标题。
    Field.Store.NO
    :原文不存储在索引文件中,搜索结果命中后,再根据其他附加属性如文件的Path,数据库的主键等,重新连接打开原文,适合原文内容较大的情况。
    Field.Store.COMPRESS
    压缩存储;
  • termVectorLucene 1.4.3新增的它提供一种向量机制来进行模糊查询,很少用。

     上面所说的Field属性与lucene1.4.3版本的有比较大的不同,在旧版的1.4.3lucene是通过Field.Keyword(...),FieldUnIndexed(...),FieldUnstored(...)Field.Text(...)来设置不同字段的类型以达到不同的用途,而当前版本由Field.IndexField.Store两个字段的不同组合来达到上述效果。
还有一点说明,其中的两个构造函数其默认的值为Field.Store.NOField.Index.TOKENIZED。:

Field(String name, Reader reader)

Field(String name, Reader reader, Field.TermVector termVector)

  • 限制Field的长度:
    IndexWriter
    类提供了一个setMaxFieldLength的方法来对Field的长度进行限制,看一下源代码就知道其默认值为10000;我们可以在使用时重新设置此参数。如果使用默认值,那么Lucene就仅仅对文档的前面的10000term进行索引,超过这一个数的文档就不会被建立索引。

1.2 索引的合并、删除、优化

IndexWriter中的addIndexes方法将索引进行合并;当在不同的地方创建了索引后,如果需要将索引合并,这时候使用addIndexes方法就显得很有意义。

可以通过IndexReader类从索引中进行文档的删除。IndexReader是很特别的一个类,看源代码就知道它主要是通过自身的静态方法来完成构造的。示例:

IndexReader reader = IndexReader.open("C:\\springside");

reader.deleteDocument(X);                            //这里的X是一个int的常数;不推荐这一种删除方法

reader.deleteDocuments(new Term("name","springside"));//这是另一种删除索引的方法,按字段来删除,推荐使用这一种做法

reader.close();

优化索引:可以使用IndexWriter类的optimize方法来进行优先,它会将多个Segment进行合并,组成一个新的Segment,可以加快建立索引后搜索的速度。另外需要注意的一点,optimize方法会降低建立索引的速度,而且要求的磁盘空间会增加。

2. 进行搜索时最常用的几个术语

IndexSearcher:lucene中最基本的检索工具,所有的检索都会用到IndexSearcher工具。初始化IndexSearcher需要设置索引存放的路径,让查询器能定位索引而进行搜索。

Query:查询,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。

QueryParser: 是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。

Hits:在搜索完成之后,需要把搜索结果返回并显示给用户,只有这样才算是完成搜索的目的。在lucene中,搜索的结果的集合是用Hits类的实例来表示的。Hits对象中主要方法有:

length(): 返回搜索结果的总数,下面简单的用法中有用到Hit的这一个方法

doc(int n): 返回第n个文档

iterator(): 返回一个迭代器

这里再提一下Hits,这也是Lucene比较精彩的地方,熟悉hibernate的朋友都知道hibernate有一个延迟加载的属性,同样,Lucene也有。Hits对象也是采用延迟加载的方式返回结果的,当要访问某个文档时,Hits对象就在内部对Lucene的索引又进行一次检索,最后才将结果返回到页面显示。

3. 一个简单的实例:

首先把lucene的包放在classpath路径中去,写下面一个简单的类:

public class FSDirectoryTest {

    //建立索引的路径

    public static final String path = "c:\\index2";

 

    public static void main(String[] args) throws Exception {

        Document doc1 = new Document();

        doc1.add( new Field("name", "lighter springside com",Field.Store.YES,Field.Index.TOKENIZED));

 

        Document doc2 = new Document();

        doc2.add(new Field("name", "lighter blog",Field.Store.YES,Field.Index.TOKENIZED));

 

        IndexWriter writer = new IndexWriter(FSDirectory.getDirectory(path, true), new StandardAnalyzer(), true);

        writer.addDocument(doc1);

        writer.addDocument(doc2);

        writer.close();

 

        IndexSearcher searcher = new IndexSearcher(path);

        Hits hits = null;

        Query query = null;

        QueryParser qp = new QueryParser("name",new StandardAnalyzer());

 

        query = qp.parse("lighter");

        hits = searcher.search(query);

        System.out.println("查找\"lighter\" " + hits.length() + "个结果");

 

        query = qp.parse("springside");

        hits = searcher.search(query);

        System.out.println("查找\"springside\" " + hits.length() + "个结果");

 

    }

}

执行的结果:

查找"lighter" 2个结果

查找"springside" 1个结果

4. 一个复杂一点的实例

windows系统下的的C盘,建一个名叫s的文件夹,在该文件夹里面随便建三个txt文件,随便起名啦,就叫"1.txt","2.txt""3.txt"
其中1.txt的内容如下:

springside社区

更大进步,吸引更多用户,更多贡献

2007

"2.txt""3.txt"的内容也可以随便写几写,这里懒写,就复制一个和1.txt文件的内容一样吧

下载lucene包,放在classpath路径中,然后建立索引:

/**

 * author lighter date 2006-8-7

 */

public class LuceneExample {

        public static void main(String[] args) throws Exception {

 

               File fileDir = new File("c:\\s");     // 指明要索引文件夹的位置,这里是C盘的S文件夹下

               File indexDir = new File("c:\\index"); // 这里放索引文件的位置

               File[] textFiles = fileDir.listFiles();

 

               Analyzer luceneAnalyzer = new StandardAnalyzer();

               IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);

              indexFile(luceneAnalyzer,indexWriter, textFiles);

               indexWriter.optimize();//optimize()方法是对索引进行优化

               indexWriter.close();

        }

 

        public static void indexFile(Analyzer luceneAnalyzer,IndexWriter indexWriter,File[] textFiles) throws Exception

        {

               //增加document到索引去

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

                       if (textFiles[i].isFile() && textFiles[i].getName().endsWith(".txt")) {

                               String temp = FileReaderAll(textFiles[i].getCanonicalPath(),"GBK");

                               Document document = new Document();

                               Field FieldBody = new Field("body", temp, Field.Store.YES,Field.Index.TOKENIZED);

                               document.add(FieldBody);

                               indexWriter.addDocument(document);

                       }

               }

        }

        public static String FileReaderAll(String FileName, String charset)throws IOException {

               BufferedReader reader = new BufferedReader(new InputStreamReader(

                               new FileInputStream(FileName), charset));

               String line = "";

               String temp = "";

               while ((line = reader.readLine()) != null) {

                       temp += line;

               }

               reader.close();

               return temp;

        }

}

执行查询:

public class TestQuery {

    public static void main(String[] args) throws IOException, ParseException {

        Hits hits = null;

        String queryString = "社区";

        Query query = null;

        IndexSearcher searcher = new IndexSearcher("c:\\index");

 

        Analyzer analyzer = new StandardAnalyzer();

        try {

            QueryParser qp = new QueryParser("body", analyzer);

            query = qp.parse(queryString);

        } catch (ParseException e) {

        }

        if (searcher != null) {

            hits = searcher.search(query);

            if (hits.length() > 0) {

                System.out.println("找到:" + hits.length() + " 个结果!");

            }

        }

    }

}

执行结果:

找到:3 个结果!

5Hibernatelucene的结合使用:

参考这一篇文章,里面讲得很详细
http://wiki.redsaga.com/confluence/display/HART/Hibernate+Lucene+Integration

 

分享到:
评论

相关推荐

    Lucene 基础指南.doc

    《Lucene基础指南》 Lucene是一个由Apache软件基金会开发的全文搜索引擎库,采用Java语言编写,具有强大的功能。它的核心API简洁而高效,主要处理两大任务:建立索引和执行搜索。 1. 建立索引 - Document:在...

    Lucene开发指南

    总的来说,这份《Lucene开发指南》提供了从基础到进阶的全面学习路径,覆盖了Lucene的主要功能和应用场景。通过系统学习这些笔记,开发者可以熟练掌握Lucene的使用,从而在实际项目中实现高效、精准的全文检索功能。

    lucene2.9开发指南

    《Lucene2.9开发指南》是一份专为初级开发者准备的资料,旨在详细介绍如何使用开源全文搜索工具包Lucene2.9.1。Lucene作为一个强大的文本搜索库,其核心功能包括建立索引和执行搜索。以下是关于Lucene2.9开发的一些...

    lucene入门指南

    **Lucene 入门指南** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发并维护。它是 Java 开发人员用来构建搜索引擎应用程序的基础工具。本指南将帮助初学者理解 Lucene 的核心概念,以及如何利用它来...

    Lucene入门指南

    ### Lucene入门指南 #### 一、Lucene简介 **Lucene** 是一款高性能的全文检索引擎工具包,由 **Apache 软件基金会** 的 **Jakarta 项目组** 开发并维护。作为一款完全开放源代码的工具,Lucene 提供了一系列的功能...

    lucene in action英文版 lucene 3.30包

    1. **Lucene基础** Lucene是基于Java的开源搜索库,它的核心功能包括索引和搜索文本。索引过程将文本数据转换为可搜索的结构,搜索过程则根据用户输入的查询快速找到相关的文档。Lucene支持多种搜索类型,如布尔...

    Lucene资料大全(包括Lucene_in_Action书等)

    这份PPT可能包含对Lucene基础知识的快速概览,如Lucene的主要特点、基本用法,以及适合初学者的示例代码。它可能以简洁易懂的方式解释Lucene的关键概念,对于快速入门Lucene是非常有价值的资源。 总的来说,这个...

    lucene指南

    **Lucene 指南** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发,广泛应用于各种搜索引擎的构建。它提供了一个简单但功能强大的API,允许开发者在自己的应用中实现全文检索功能。Lucene 入门需要...

    lucene in action源码

    《Lucene in Action》是关于Apache Lucene的权威指南,这本书深入浅出地介绍了全文搜索引擎的构建和优化。源码的提供使得读者可以更直观地理解Lucene的工作原理,这对于学习和开发基于Lucene的搜索应用非常有帮助。...

    Lucene的的学习资料及案例

    **Lucene学习指南** Lucene是一个高性能、全文检索库,由Apache软件基金会开发并维护,是Java编程语言中广泛使用的搜索引擎库。它提供了一个简单的API,使得开发者能够方便地在应用中实现全文检索功能。本篇文章将...

    lucene 数据库

    《Lucene 数据库:深入解析与实践指南》 Lucene,作为一款开源的全文检索库,是Java领域中广泛使用的搜索引擎框架。它为开发者提供了强大的文本检索功能,使得在大量数据中快速查找相关信息变得轻而易举。在这个...

    Lucene 实时搜索视频详解

    1. **入门指南**:介绍 Lucene 的安装、配置以及基本操作。 2. **索引构建**:详细解释如何创建、更新和删除索引,以及如何选择合适的分析器。 3. **查询语法**:深入学习 Lucene 的查询语言,包括布尔运算符、短语...

    Lucene In Action

    1. **Lucene基础知识**:Lucene的核心概念包括文档、字段、术语和倒排索引。文档是存储信息的基本单元,字段是文档的组成部分,而术语是经过分词后的单词。倒排索引是Lucene实现高效搜索的关键,它将每个术语与包含...

    Lucene.In.Action.2nd.Edition

    这些概念构成了Lucene搜索引擎的基础。 2. **索引创建**:学习如何将文本数据转换为可搜索的Lucene索引,包括分词、分析器的选择和使用,以及如何处理不同的数据类型。 3. **分析器(Analyzer)**:分析器在Lucene...

    Lucene常用的Demo

    掌握这些基础后,你就可以进一步探索Lucene的高级特性,如近实时搜索、多线程索引、复杂查询语法等。记住,实践是检验理解的最好方式,动手尝试这些示例,结合官方文档,你的Lucene技能将得到显著提升。

    Lucene实战

    《Lucene实战》第二版是一本深入探讨Apache Lucene搜索引擎库的权威指南。这本书主要针对开发者,特别是那些希望在自己的应用程序中集成全文搜索功能的人。Lucene是一个高性能、全文本检索库,它允许开发人员轻松地...

    Lucene in Action 2nd Edition

    1. **Lucene基础**:介绍Lucene的基本架构和工作原理,包括倒排索引的概念,以及如何使用Lucene进行文档的索引和存储。 2. **安装与配置**:详细讲解如何在Java环境中集成Lucene,包括依赖管理和配置设置,以及如何...

    lucene in action 电子版

    - **目标读者**:对于那些从事搜索引擎开发或者希望在自己的应用中集成搜索功能的专业人士来说,“Lucene in Action”提供了一套完整的指南。 #### 二、Lucene的核心概念 - **章节1:初识Lucene** - **信息组织与...

Global site tag (gtag.js) - Google Analytics