`

lucene索引文档

阅读更多

用Lucene索引文档

接下来我将一步一步的来演示如何利用 Lucene 为你的文档创建索引。只要你能将要索引的文件转化成文本格式,Lucene 就能为你的文档建立索引。比如,如果你想为 HTML 文档或者 PDF 文档建立索引,那么首先你就需要从这些文档中提取出文本信息,然后把文本信息交给 Lucene 建立索引。我们接下来的例子用来演示如何利用 Lucene 为后缀名为 txt 的文件建立索引。

1. 准备文本文件

首先把一些以 txt 为后缀名的文本文件放到一个目录中,比如在 Windows 平台上,你可以放到 C:\\files_to_index 下面。

2. 创建索引

清单1是为我们所准备的文档创建索引的代码。


清单1:用 Lucene 索引你的文档

package lucene.index;
            import java.io.File;
            import java.io.FileReader;
            import java.io.Reader;
            import java.util.Date;
            import org.apache.lucene.analysis.Analyzer;
            import org.apache.lucene.analysis.standard.StandardAnalyzer;
            import org.apache.lucene.document.Document;
            import org.apache.lucene.document.Field;
            import org.apache.lucene.index.IndexWriter;
            /**
            * This class demonstrates the process of creating an index with Lucene
            * for text files in a directory.
            */
            public class TextFileIndexer {
            public static void main(String[] args) throws Exception{
            //fileDir is the directory that contains the text files to be indexed
            File   fileDir  = new File("C:\\files_to_index ");
            //indexDir is the directory that hosts Lucene's index files
            File   indexDir = new File("C:\\luceneIndex");
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            File[] textFiles  = fileDir.listFiles();
            long startTime = new Date().getTime();
            //Add documents to the index
            for(int i = 0; i < textFiles.length; i++){
            if(textFiles[i].isFile() >> textFiles[i].getName().endsWith(".txt")){
            System.out.println("File " + textFiles[i].getCanonicalPath()
            + " is being indexed");
            Reader textReader = new FileReader(textFiles[i]);
            Document document = new Document();
            document.add(Field.Text("content",textReader));
            document.add(Field.Text("path",textFiles[i].getPath()));
            indexWriter.addDocument(document);
            }
            }
            indexWriter.optimize();
            indexWriter.close();
            long endTime = new Date().getTime();
            System.out.println("It took " + (endTime - startTime)
            + " milliseconds to create an index for the files in the directory "
            + fileDir.getPath());
            }
            }

正如清单1所示,你可以利用 Lucene 非常方便的为文档创建索引。接下来我们分析一下清单1中的比较关键的代码,我们先从下面的一条语句开始看起。


Analyzer luceneAnalyzer = new StandardAnalyzer();

这条语句创建了类 StandardAnalyzer 的一个实例,这个类是用来从文本中提取出索引项的。它只是抽象类 Analyzer 的其中一个实现。Analyzer 也有一些其它的子类,比如 SimpleAnalyzer 等。

我们接着看另外一条语句:


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

这条语句创建了类 IndexWriter 的一个实例,该类也是 Lucene 索引机制里面的一个关键类。这个类能创建一个新的索引或者打开一个已存在的索引并为该所引添加文档。我们注意到该类的构造函数接受三个参数,第一个参数指定了存储索引文件的路径。第二个参数指定了在索引过程中使用什么样的分词器。最后一个参数是个布尔变量,如果值为真,那么就表示要创建一个新的索引,如果值为假,就表示打开一个已经存在的索引。

接下来的代码演示了如何添加一个文档到索引文件中。


Document document = new Document();
            document.add(Field.Text("content",textReader));
            document.add(Field.Text("path",textFiles[i].getPath()));
            indexWriter.addDocument(document);

首先第一行创建了类 Document 的一个实例,它由一个或者多个的域(Field)组成。你可以把这个类想象成代表了一个实际的文档,比如一个 HTML 页面,一个 PDF 文档,或者一个文本文件。而类 Document 中的域一般就是实际文档的一些属性。比如对于一个 HTML 页面,它的域可能包括标题,内容,URL 等。我们可以用不同类型的 Field 来控制文档的哪些内容应该索引,哪些内容应该存储。如果想获取更多的关于 Lucene 的域的信息,可以参考 Lucene 的帮助文档。代码的第二行和第三行为文档添加了两个域,每个域包含两个属性,分别是域的名字和域的内容。在我们的例子中两个域的名字分别是"content"和"path"。分别存储了我们需要索引的文本文件的内容和路径。最后一行把准备好的文档添加到了索引当中。

当我们把文档添加到索引中后,不要忘记关闭索引,这样才保证 Lucene 把添加的文档写回到硬盘上。下面的一句代码演示了如何关闭索引。


indexWriter.close();

利用清单1中的代码,你就可以成功的将文本文档添加到索引中去。接下来我们看看对索引进行的另外一种重要的操作,从索引中删除文档。




 

从索引中删除文档

类IndexReader负责从一个已经存在的索引中删除文档,如清单2所示。


清单2:从索引中删除文档

File   indexDir = new File("C:\\luceneIndex");
            IndexReader ir = IndexReader.open(indexDir);
            ir.delete(1);
            ir.delete(new Term("path","C:\\file_to_index\lucene.txt"));
            ir.close();

在清单2中,第二行用静态方法 IndexReader.open(indexDir) 初始化了类 IndexReader 的一个实例,这个方法的参数指定了索引的存储路径。类 IndexReader 提供了两种方法去删除一个文档,如程序中的第三行和第四行所示。第三行利用文档的编号来删除文档。每个文档都有一个系统自动生成的编号。第四行删除了路径为"C:\\file_to_index\lucene.txt"的文档。你可以通过指定文件路径来方便的删除一个文档。值得注意的是虽然利用上述代码删除文档使得该文档不能被检索到,但是并没有物理上删除该文档。Lucene 只是通过一个后缀名为 .delete 的文件来标记哪些文档已经被删除。既然没有物理上删除,我们可以方便的把这些标记为删除的文档恢复过来,如清单 3 所示,首先打开一个索引,然后调用方法 ir.undeleteAll() 来完成恢复工作。


清单3:恢复已删除文档

File   indexDir = new File("C:\\luceneIndex");
            IndexReader ir = IndexReader.open(indexDir);
            ir.undeleteAll();
            ir.close();

你现在也许想知道如何物理上删除索引中的文档,方法也非常简单。清单 4 演示了这个过程。


清单4:如何物理上删除文档

File   indexDir = new File("C:\\luceneIndex");
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,false);
            indexWriter.optimize();
            indexWriter.close();

在清单 4 中,第三行创建了类 IndexWriter 的一个实例,并且打开了一个已经存在的索引。第 4 行对索引进行清理,清理过程中将把所有标记为删除的文档物理删除。

Lucene 没有直接提供方法对文档进行更新,如果你需要更新一个文档,那么你首先需要把这个文档从索引中删除,然后把新版本的文档加入到索引中去。




提高索引性能

利用 Lucene,在创建索引的工程中你可以充分利用机器的硬件资源来提高索引的效率。当你需要索引大量的文件时,你会注意到索引过程的瓶颈是在往磁盘上写索引文件的过程中。为了解决这个问题, Lucene 在内存中持有一块缓冲区。但我们如何控制 Lucene 的缓冲区呢?幸运的是,Lucene 的类 IndexWriter 提供了三个参数用来调整缓冲区的大小以及往磁盘上写索引文件的频率。

1.合并因子(mergeFactor)

这个参数决定了在 Lucene 的一个索引块中可以存放多少文档以及把磁盘上的索引块合并成一个大的索引块的频率。比如,如果合并因子的值是 10,那么当内存中的文档数达到 10 的时候所有的文档都必须写到磁盘上的一个新的索引块中。并且,如果磁盘上的索引块的隔数达到 10 的话,这 10 个索引块会被合并成一个新的索引块。这个参数的默认值是 10,如果需要索引的文档数非常多的话这个值将是非常不合适的。对批处理的索引来讲,为这个参数赋一个比较大的值会得到比较好的索引效果。

2.最小合并文档数

这个参数也会影响索引的性能。它决定了内存中的文档数至少达到多少才能将它们写回磁盘。这个参数的默认值是10,如果你有足够的内存,那么将这个值尽量设的比较大一些将会显著的提高索引性能。

3.最大合并文档数

这个参数决定了一个索引块中的最大的文档数。它的默认值是 Integer.MAX_VALUE,将这个参数设置为比较大的值可以提高索引效率和检索速度,由于该参数的默认值是整型的最大值,所以我们一般不需要改动这个参数。

清单 5 列出了这个三个参数用法,清单 5 和清单 1 非常相似,除了清单 5 中会设置刚才提到的三个参数。


清单5:提高索引性能

/**
            * This class demonstrates how to improve the indexing performance
            * by adjusting the parameters provided by IndexWriter.
            */
            public class AdvancedTextFileIndexer  {
            public static void main(String[] args) throws Exception{
            //fileDir is the directory that contains the text files to be indexed
            File   fileDir  = new File("C:\\files_to_index");
            //indexDir is the directory that hosts Lucene's index files
            File   indexDir = new File("C:\\luceneIndex");
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            File[] textFiles  = fileDir.listFiles();
            long startTime = new Date().getTime();
            int mergeFactor = 10;
            int minMergeDocs = 10;
            int maxMergeDocs = Integer.MAX_VALUE;
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            indexWriter.mergeFactor = mergeFactor;
            indexWriter.minMergeDocs = minMergeDocs;
            indexWriter.maxMergeDocs = maxMergeDocs;
            //Add documents to the index
            for(int i = 0; i < textFiles.length; i++){
            if(textFiles[i].isFile() >> textFiles[i].getName().endsWith(".txt")){
            Reader textReader = new FileReader(textFiles[i]);
            Document document = new Document();
            document.add(Field.Text("content",textReader));
            document.add(Field.Keyword("path",textFiles[i].getPath()));
            indexWriter.addDocument(document);
            }
            }
            indexWriter.optimize();
            indexWriter.close();
            long endTime = new Date().getTime();
            System.out.println("MergeFactor: " + indexWriter.mergeFactor);
            System.out.println("MinMergeDocs: " + indexWriter.minMergeDocs);
            System.out.println("MaxMergeDocs: " + indexWriter.maxMergeDocs);
            System.out.println("Document number: " + textFiles.length);
            System.out.println("Time consumed: " + (endTime - startTime) + " milliseconds");
            }
            }

通过这个例子,我们注意到在调整缓冲区的大小以及写磁盘的频率上面 Lucene 给我们提供了非常大的灵活性。现在我们来看一下代码中的关键语句。如下的代码首先创建了类 IndexWriter 的一个实例,然后对它的三个参数进行赋值。


int mergeFactor = 10;
            int minMergeDocs = 10;
            int maxMergeDocs = Integer.MAX_VALUE;
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            indexWriter.mergeFactor = mergeFactor;
            indexWriter.minMergeDocs = minMergeDocs;
            indexWriter.maxMergeDocs = maxMergeDocs;

下面我们来看一下这三个参数取不同的值对索引时间的影响,注意参数值的不同和索引之间的关系。我们为这个实验准备了 10000 个测试文档。表 1 显示了测试结果。


表1:测试结果
表1:测试结果

通过表 1,你可以清楚地看到三个参数对索引时间的影响。在实践中,你会经常的改变合并因子和最小合并文档数的值来提高索引性能。只要你有足够大的内存,你可以为合并因子和最小合并文档数这两个参数赋尽量大的值以提高索引效率,另外我们一般无需更改最大合并文档数这个参数的值,因为系统已经默认将它设置成了最大。




Lucene 索引文件结构分析

在分析 Lucene 的索引文件结构之前,我们先要理解反向索引(Inverted index)这个概念,反向索引是一种以索引项为中心来组织文档的方式,每个索引项指向一个文档序列,这个序列中的文档都包含该索引项。相反,在正向索引中,文档占据了中心的位置,每个文档指向了一个它所包含的索引项的序列。你可以利用反向索引轻松的找到那些文档包含了特定的索引项。Lucene正是使用了反向索引作为其基本的索引结构。



索引文件的逻辑视图

在Lucene 中有索引块的概念,每个索引块包含了一定数目的文档。我们能够对单独的索引块进行检索。图 2 显示了 Lucene 索引结构的逻辑视图。索引块的个数由索引的文档的总数以及每个索引块所能包含的最大文档数来决定。


图2:索引文件的逻辑视图
图2:索引文件的逻辑视图


Lucene 中的关键索引文件

下面的部分将会分析Lucene中的主要的索引文件,可能分析有些索引文件的时候没有包含文件的所有的字段,但不会影响到对索引文件的理解。

1.索引块文件

这个文件包含了索引中的索引块信息,这个文件包含了每个索引块的名字以及大小等信息。表 2 显示了这个文件的结构信息。


表2:索引块文件结构
表2:索引块文件结构

2.域信息文件

我们知道,索引中的文档由一个或者多个域组成,这个文件包含了每个索引块中的域的信息。表 3 显示了这个文件的结构。


表3:域信息文件结构
表3:域信息文件结构

3.索引项信息文件

这是索引文件里面最核心的一个文件,它存储了所有的索引项的值以及相关信息,并且以索引项来排序。表 4 显示了这个文件的结构。


表4:索引项信息文件结构
表4:索引项信息文件结构

4.频率文件

这个文件包含了包含索引项的文档的列表,以及索引项在每个文档中出现的频率信息。如果Lucene在索引项信息文件中发现有索引项和搜索词相匹配。那么 Lucene 就会在频率文件中找有哪些文件包含了该索引项。表5显示了这个文件的一个大致的结构,并没有包含这个文件的所有字段。


表5:频率文件的结构
表5:频率文件的结构

5.位置文件

这个文件包含了索引项在每个文档中出现的位置信息,你可以利用这些信息来参与对索引结果的排序。表 6 显示了这个文件的结构


表6:位置文件的结构
表6:位置文件的结构

到目前为止我们介绍了 Lucene 中的主要的索引文件结构,希望能对你理解 Lucene 的物理的存储结构有所帮助。

分享到:
评论

相关推荐

    毕设 Lucene解析索引PDF文档的内容

    iTextPDFExtractor.java ------ ...--PDFBox创建PDF文件的Lucene索引 PDFBoxPathIndex.java ------- --PDFBox创建指定目录PDF文档索引 POIOfficeExtractor.java ----- -- POI处理Excel和Word文档代码

    Lucene索引器实例

    **Lucene索引器实例详解** Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,被广泛应用于各种搜索引擎的构建。它提供了一个高级的、灵活的、可扩展的接口,使得开发者能够轻松地在应用程序中实现全文...

    lucene索引查看工具及源码

    Luke 提供了诸如查看文档字段、搜索索引、查看倒排索引结构等功能,对于开发者来说是了解和调试 Lucene 索引的利器。 Luke 的源码也公开在 GitHub 上,这对于想深入理解 Lucene 内部机制的开发者来说是一个宝贵的...

    lucene索引查看程序及代码

    《深入理解Lucene索引查看程序与代码》 在信息技术领域,搜索引擎的高效运作离不开底层索引技术的支持,而Lucene作为Apache软件基金会的一个开放源代码项目,正是一个强大的全文检索库,它提供了高效的文本搜索功能...

    lucene 索引 查看 工具

    1. **Lucene 索引**:Lucene 的索引是一种倒排索引,它将文档中的词项(tokens)映射到包含这些词项的文档列表。这种数据结构使得搜索过程高效,能够在大量文档中快速找到包含特定关键词的文档。 2. **Luke 工具**...

    深入 Lucene 索引机制

    以下是对Lucene索引机制的详细解析: 一、Lucene的索引过程 1. 文档分析:当向Lucene添加文档时,首先会经过一个分词器(Tokenizer),将文本拆分成一系列的词项(Token)。接着,这些词项会被过滤(Filter)和...

    Lucene索引和查询

    **Lucene索引和查询** Lucene是Apache软件基金会的开放源码全文搜索引擎库,它提供了文本检索的核心工具,使得开发者能够快速构建自己的搜索应用。本项目中的代码旨在展示如何利用Lucene对多个文件夹下的数据进行...

    lucene索引查看工具luck7.4.0

    `Luck`,全称`Luke`,是一款强大的Lucene索引浏览器和分析器工具,可以帮助开发者、数据分析师以及对Lucene感兴趣的人员查看、理解和调试Lucene索引。 `Luke 7.4.0`是这款工具的一个特定版本,它专门设计用来与...

    Lucene索引文件查看工具lukeall4.7.1

    《深入理解Lucene索引文件查看工具LukeAll 4.7.1》 在信息检索领域,Lucene作为一款强大的全文搜索引擎库,被广泛应用在各种数据检索系统中。然而,对于开发者来说,理解并调试Lucene创建的索引文件并非易事。此时...

    Lucene 索引的简单使用

    以上就是关于“Lucene索引的简单使用”的详细介绍,包括其核心概念、创建和查询索引的步骤以及一些高级特性。希望对你理解和应用Lucene有所帮助。在实际开发中,可以根据需求选择合适的Analyzer,优化索引策略,以...

    很好的lucene索引查看工具,欢迎各位lucene研究者前来下载

    本文将详细介绍一款被称为“很好的lucene索引查看工具”的实用软件,旨在帮助用户更好地理解和调试Lucene索引。 Lucene索引查看工具是一款专为Lucene设计的可视化工具,它允许用户直观地浏览和分析由Lucene创建的...

    lucene索引结构原理

    **Lucene索引结构原理** Lucene是Apache软件基金会的开放源代码全文搜索引擎库,它为Java开发人员提供了强大的文本搜索功能。理解Lucene的索引结构原理对于优化搜索性能和设计高效的搜索应用至关重要。 首先,我们...

    lucene索引文件格式介绍

    以下是对Lucene索引文件格式的详细说明。 首先,我们要理解Lucene索引的基本结构。一个Lucene索引位于一个文件夹中,这个文件夹包含了多个段(Segment)。每个段是独立的,包含了一组文档,并且可以与其他段合并。...

    lucene 索引小示例

    《Lucene索引小示例解析》 Lucene是一个高性能、全文检索库,它由Apache软件基金会开发并维护。在Java编程环境中,Lucene被广泛应用于构建搜索功能,特别是对于大量文本数据的高效检索。本篇文章将通过一个简单的小...

    luke源码--查看lucene索引文件

    《深入理解Luke:洞察Lucene索引文件》 在信息技术领域,搜索引擎的高效运作离不开对数据的快速检索,而Lucene作为开源全文检索库,扮演了核心角色。在这个过程中,Luke工具提供了一种直观的方式,让我们能够查看和...

    Lucene索引的基本操作

    本文将深入探讨Lucene索引的基本操作,包括如何添加文档到索引、更新已有的索引以及相关的测试代码。 ### 1. 初始化Lucene环境 首先,我们需要导入Lucene的相关库。在Java项目中,可以通过Maven或Gradle等构建工具...

    Lucene读取索引文件

    然后,创建`IndexReader`实例,它提供了访问索引文档的方法,如`reader.document(docId)`,可以获取特定文档的信息。 接着,通过`IndexSearcher`对象进行查询操作。`IndexSearcher`提供了`search(Query query, int ...

    lucene索引结构原理.docx

    而在Lucene中,基本单位是Document,它同样由多个字段组成,但Lucene索引的是这些字段的内容,以加速文本检索。 - **索引构建**:Lucene支持增量索引和批量索引,可以处理数据源的小幅变化或大规模数据。数据库通常...

    lucene-core-7.2.1-API文档-中文版.zip

    包含翻译后的API文档:lucene-core-7.2.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.lucene:lucene-core:7.2.1; 标签:apache、lucene、core、中文文档、jar包、java; 使用方法:解压翻译后的API...

Global site tag (gtag.js) - Google Analytics