`
weitao1026
  • 浏览: 1034376 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Lucene检索的一系列流程

阅读更多
介绍了Lucene检索的一系列流程,本篇来看下Lucene中一个特殊的Directory的实现之FileSwitchDirectory,顾名思义,从字面上的意思来理解是一个基于文件目录切换的一个实现,实际上也正是如此。

那么,此类的作用是什么呢? 我们都知道lucene的索引文件是非常松散灵活的,各个文件格式之间相互独立而又有联系,在Lucenen检索的时候,会并行的打开所有的段文件,然后合并结果集至一个公共队列里返回。

Lucene的Directory基类,提供了非常丰富的子类实现,为什么如此呢,其实跟不同的操作系统和平台有紧密的联系,所以在我们的代码里,经常会使用FSDirectory的静态方法来打开一个能在我们所使用的平台上发挥最大优势的Directory,在源码里我们可以发现这个方法里面是对主流的操作系统进行了判断和选择后,会给我们返回一个合适的Directory,可能这个方法在不同的操作平台上返回不一样的Directory的实现,这一点是很正常的。




Java代码 复制代码 收藏代码
1.public static FSDirectory open(File path, LockFactory lockFactory) throws IOException { 
2.   if ((Constants.WINDOWS || Constants.SUN_OS || Constants.LINUX) 
3.         && Constants.JRE_IS_64BIT && MMapDirectory.UNMAP_SUPPORTED) { 
4.     return new MMapDirectory(path, lockFactory); 
5.   } else if (Constants.WINDOWS) { 
6.     return new SimpleFSDirectory(path, lockFactory); 
7.   } else { 
8.     return new NIOFSDirectory(path, lockFactory); 
9.   } 
10. } 


FileSwitchDirectory的出现,可以使我们组合不同Directory的优点,来充分利用我们的系统资源,我们都知道使用内存索引RAMDirectory来访问索引其速度和效率都是非常优异的,然后,有时候我们的数据量大的惊人,以至于内存中根本放不下这个索引文件,那么这时候我们既想获取高效的索引访问性能,又想获取读取和检索大索引的优异的并发性能,这时候我们怎么做呢?

这时候就是该FileSwitchDirectory大显身手的时候了,利用这个类,我们可以轻而易举的结合任意2个Directory的优异点,来为我们所用,下面我们先来看下FileSwitchDirectory在源码里的构造实现。




Java代码 复制代码 收藏代码
1./**
2.   * @param primaryExtensions 由主索引负责打开的文件
3.   * @param primaryDir 主索引目录
4.   * @param secondaryDir 从索引目录
5.   * @param doClose 是否在关闭时关闭所有Directory的资源
6.   * **/ 
7.  public FileSwitchDirectory(Set<String> primaryExtensions, Directory primaryDir, Directory secondaryDir, boolean doClose) { 
8.    this.primaryExtensions = primaryExtensions; 
9.    this.primaryDir = primaryDir; 
10.    this.secondaryDir = secondaryDir; 
11.    this.doClose = doClose; 
12.    this.lockFactory = primaryDir.getLockFactory(); 
13.  } 


由构造方法可以看出FileSwitchDirectory是需要2个Directory的实现才可以组装起来,而通过第一个参数我们可以指定主索引需要加载的索引文件,其它的将会由从Directory来实现,由此达到,快速切换不同的Directory来获取他们各自的优点。

一般情况下我们会将fdt和fdx文件放在NIODirectory里,因为这两个文件分别存储的是文档的正向信息包含具体的term,fdx文件是fdt文件的一个索引文件,实际上在后来,所有的文本数据都会保存在fdt里,索引在索引非常大的时候,这两个文件是最占容量的,所以我们选择将此放入NIO中,由此来访问大索引信息,其他的一些段信息文件,字典文件,放入内存索引中由此来获取更高的检索效率。
下面是散仙的一个示例的索引截图:






注意上图中可能大家会发现tim的项词典文件,也挺大的,散仙在这里解释一下,散仙在索引只索引了2个非常短的字段,然后循环添加了1万次,在实际项目中,肯定是多个字段组成且文本内容会比较多,那个时候索引出来的数据fdt文件一般都是最大的数据文件。

实现切换索引的代码如下:




Java代码 复制代码 收藏代码
1.String path="E:\\1111111111111111111\\1\\"; 
2.   try{ 
3.       //添加放置在nio文件里的索引文件 
4.       Set<String> files=new HashSet<>(); 
5.       files.add("fdt"); 
6.       files.add("fdx"); 
7.      
8.       Directory d1=FSDirectory.open(new File(path));//装载磁盘索引 
9.       RAMDirectory map=new RAMDirectory(d1,IOContext.READ);//放置内存索引 
10.       NIOFSDirectory nio=new NIOFSDirectory(new File(path));//基于并发大文件的NIO索引 
11.       FileSwitchDirectory fsd=new FileSwitchDirectory(files,nio,map,true); //切换实现 
12.       for(String s:fsd.listAll()){ 
13.           //System.out.println(s); 
14.           System.out.println("文件:"+s+"  读取类型: "+fsd.getDirectory(s)); 
15.             
16.       } 



运行效果如下所示:



Java代码 复制代码 收藏代码
1.文件:_2.si  读取类型: org.apache.lucene.store.RAMDirectory@6a059fa4 lockFactory=org.apache.lucene.store.SingleInstanceLockFactory@1733fe5d 
2.文件:_2_Lucene41_0.tim  读取类型: org.apache.lucene.store.RAMDirectory@6a059fa4 lockFactory=org.apache.lucene.store.SingleInstanceLockFactory@1733fe5d 
3.文件:segments.gen  读取类型: org.apache.lucene.store.RAMDirectory@6a059fa4 lockFactory=org.apache.lucene.store.SingleInstanceLockFactory@1733fe5d 
4.文件:_2.fdt  读取类型: org.apache.lucene.store.NIOFSDirectory@E:\1111111111111111111\1 lockFactory=org.apache.lucene.store.NativeFSLockFactory@37263a93 
5.文件:segments_2  读取类型: org.apache.lucene.store.RAMDirectory@6a059fa4 lockFactory=org.apache.lucene.store.SingleInstanceLockFactory@1733fe5d 
6.文件:_2_Lucene41_0.doc  读取类型: org.apache.lucene.store.RAMDirectory@6a059fa4 lockFactory=org.apache.lucene.store.SingleInstanceLockFactory@1733fe5d 
7.文件:_2_Lucene41_0.tip  读取类型: org.apache.lucene.store.RAMDirectory@6a059fa4 lockFactory=org.apache.lucene.store.SingleInstanceLockFactory@1733fe5d 
8.文件:_2.fdx  读取类型: org.apache.lucene.store.NIOFSDirectory@E:\1111111111111111111\1 lockFactory=org.apache.lucene.store.NativeFSLockFactory@37263a93 
9.文件:_2.fnm  读取类型: org.apache.lucene.store.RAMDirectory@6a059fa4 lockFactory=org.apache.lucene.store.SingleInstanceLockFactory@1733fe5d 



由输出结果,我们可以看出除了fdt文件和fdx文件是从NIO里打开的,其他的都会被加载到RAM里,与我们预期的假设是一致的。


最后我们来简单分析下,Lucene是如何实现索引的动态的切换?

实际上在程序一开始启动时,是打开了2个Directory,然后通过FileSwitchDirectory 组装在了一起,在一个检索请求发来时,会选择具体的索引文件打开并读取,此时就是切换目录的时候,我们可以在FileSwitchDirectory 的源码里找到如下的一段代码:




Java代码 复制代码 收藏代码
1./**
2.   * 切换目录的核心代码
3.   * @param name 具体的索引文件名
4.   * @return  返回的具体Directory
5.   * ***/ 
6.  public Directory getDirectory(String name) { 
7.    String ext = getExtension(name); 
8.    if (primaryExtensions.contains(ext)) {//在初始化的集合里判断 
9.      return primaryDir;//true,将会从主索引加载 
10.    } else { 
11.      return secondaryDir;//false将会从从索引加载 
12.    } 
13.  } 


其实,就是在启动的时候打开了同一份索引的2个不同的Directory的实现,然后通过FileSwitchDirectory 这个类,来动态的完成的索引切换的过程
分享到:
评论

相关推荐

    一种基于Lucene检索引擎的全文数据库的研究与实现

    - **索引创建**:首先,Lucene会将文档内容解析成一系列的词条(Token),并对这些词条进行一定的预处理,如去除停用词、词干提取等。 - **索引存储**:经过处理后的词条会被存储到索引中。索引通常是以倒排表的形式...

    Lucene全文检索引擎

    5. **分词器(Tokenizer)**:用于将输入的文本分解成一系列的词或短语,是文本分析的第一步。 6. **查询解析器(Query Parser)**:处理用户的搜索请求,将其转化为Lucene可以理解的查询对象。 7. **评分...

    Lucene检索数据库支持中文检索

    ### Lucene检索数据库支持中文检索 #### 一、Lucene简介与原理 ##### 1. Lucene概述 Lucene是一款高性能、全功能的文本搜索引擎库,由Java编写而成。其核心功能是为开发者提供构建搜索应用程序的基础框架。Lucene...

    lucene.net1.4.3全文检索源文件

    1. 分词(Tokenization):Lucene.NET首先通过分词器(Analyzer)将输入的文档分解成一系列的关键词(Token)。分词器会考虑语言特性,如英文中的单词边界,进行词汇切分。 2. 建立索引(Indexing):每个关键词会...

    Lucene 全文检索

    通过分析和分词,将文本转换为一系列可搜索的关键词,然后构建倒排索引,使得快速查找匹配文档变得可能。 2. **分词器(Tokenizer)**:分词器是将原始文本分割成独立的词汇单元(称为“术语”或“tokens”)的组件...

    全文检索引擎Lucene

    5. **分词器(Analyzer)**: 负责将输入的字符串分解成一系列的术语,对文本进行预处理,包括去除停用词、词干提取等。 6. **查询解析器(Query Parser)**: 将用户的查询字符串转化为Lucene能理解的查询对象,支持...

    最新全文检索 lucene-5.2.1 入门经典实例

    - **Analyzer**:文本分析器是Lucene处理文本的第一步,它负责将输入的字符串分解为一系列的词项(tokens)。在5.2.1版本中,包括了`StandardAnalyzer`和`SimpleAnalyzer`等,适用于不同语言和应用场景。 2. **...

    Lucene.Net全文检索Demo

    - **分词器(Tokenizer)**:处理输入文本,将其拆分为一系列的词语。 - **词项(Token)**:索引的基本单位,通常是一个个独立的词语。 - **倒排索引(Inverted Index)**:存储每个词项在哪些文档中出现,以及...

    开放源代码的全文检索引擎Lucene.pdf

    Lucene的索引构建逻辑围绕一系列核心对象展开,如项(Term)、域(Field)、文档(Document)、段(Segment)等。了解这些对象及其相互关系,是掌握Lucene内部工作原理的关键。 - **项(Term)**:表示索引中的单个...

    全文检索原理及Lucene实之搜索

    - **分词**:为了建立索引,首先需要将文档中的文本分割成一系列单词或词组,这个过程称为分词。 - **搜索**:用户可以通过输入查询语句来搜索索引,Lucene会返回匹配的结果。 #### Lucene的工作流程 - **索引过程...

    开放源代码的全文检索引擎Lucene终稿.pdf

    第四部分聚焦于Lucene索引构建逻辑模块的分析,详细阐述了索引构建的流程,包括对象体系的UML图,展示了Lucene内部如何处理文档、字段和术语,以及如何通过一系列步骤将这些信息转化为可搜索的索引结构。 总体而言...

    Lucene 全文检索 之 详解

    3. **分析器(Analyzer)**:分析器负责将输入的文本分解为一系列的词元(Token),并进行标准化处理,如去除停用词、词形还原等。Lucene提供了多种预设分析器,也可自定义。 4. **查询解析器(Query Parser)**:...

    LuceneDemo

    3. 分词器(Analyzer):分词器负责将文档字段的文本进行分词处理,生成一系列的关键词,这是Lucene索引的基础。不同的语言和应用场景需要选择合适的分词器。 4. 索引(Index):索引是Lucene的核心,类似于关系...

    第一个lucene程序

    1. **创建索引**:这是Lucene工作的第一步,它会把文档内容解析成一系列的术语(tokens),然后为每个术语建立倒排索引。倒排索引是一种数据结构,它允许快速查找包含特定术语的文档。 2. **索引写入**:在创建索引...

    Lucene 索引的简单使用

    - **分词器(Tokenizer)**:分词器将输入的文本分解为一系列的词语,这是建立索引的第一步。 - **分析器(Analyzer)**:分析器结合了分词器、过滤器等,负责对文本进行预处理,如去除停用词、词形还原等。 ### 2...

    Lucene全文检索引擎工具包 v7.7.3-源码.zip

    Lucene提供了一系列预定义的分析器,如StandardAnalyzer,针对英文文本进行了特殊优化,同时支持自定义分析器以适应各种语言和应用场景。 2. 文档(Document):在Lucene中,每个文档对应一个Document对象,用于...

    Lucene的原理完整版pdf

    1. **索引**:Lucene首先对文本进行索引,将文本内容转换为一系列可搜索的结构。索引过程包括分词(Tokenization)、词干提取(Stemming)、停用词处理(Stop Word Removal)等步骤。 2. **文档(Document)**:在...

    lucene3源码分析

    将文档分解成一系列的词项。 - **第三步:语言处理**。这一步骤包括去除停用词、词干提取等操作。 - **第四步:创建索引**。将处理后的词项和相关信息添加到索引中。 - **1. 创建字典**:收集所有词项并确保其唯一...

    全文检索Lucene

    - **分析器(Analyzer)**: 分析器负责将输入文本分解成一系列的关键词(Token),进行词化、过滤等操作,以适应索引和搜索的需求。 **2. Lucene的主要操作流程** 1. **创建索引(Indexing)**: 首先,读取文档...

Global site tag (gtag.js) - Google Analytics