Lucene.Net:关于索引的一些补充说明和总结

在前面的几篇关于lucene的文章中,我已经简要说明了如何利用lucene进行分词、索引和搜索。最近大部分时间耗在查资料上,看得比较多比较杂但是一贯的不够深入,还好多数都是不会影响编程实践的概念性的东西。有时候我自己也感觉到有心无力,太关注那些表面的繁文缛节性的东西有让人失掉好奇、激情和勤奋实践的风险,毕竟我个人需要专心专注的事情是解决问题而不是多知道几个概念和专业名词,要先做出东西来,虽然这样显得不是很专业。本文简单补充记录一下对于lucene创建索引有用的几个参数以及索引文件中的常见的几种格式的感性认识和总结,希望对你也有帮助。

一、提高索引速度几个有用的参数

在索引算法确定的情况下,最为影响lucene索引速度的主要是三个参数,即IndexWriter中的 mergeFactor, maxMergeDocs和RAMBufferSizeMB 。这些参数主要就是控制内外存交换和索引合并频率,从而达到提高索引速度的目的,当然这几个参数的具体设定和机器的硬件条件也密不可分。

1、mergeFactor

mergeFactor就是所谓的“合并因子”,它的作用主要是用于子索引(segment)合并的。 如你所知,lucene中索引总体上是这样进行的:索引先写入内存,触发一定限制条件后写入硬盘,生成一个独立的子索引(segment)。通常情况下,多个子索引在优化(optimize())后会合并成一个索引,否则子索引会很多,影响检索速度,而且占用的磁盘空间可能会非常大。mergeFactor这个参数就是控制当硬盘中有多少个子索引segments时,lucene就需要把这些子索引合并成一个较大一点的索引。合并的内部实现细节我也不是很清楚,但是lucene 中默认索引合并机制并不是两两合并,通常都是多个segment一次合并成一个较大索引,所以mergeFactor越大耗费内存越多,索引速度也会快些。

            IndexWriter writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);Console.WriteLine(writer.GetMergeFactor());//mergeFactor默认是10writer.SetMergeFactor(30);Console.WriteLine(writer.GetMergeFactor());//设置后,当前是30

mergeFactor默认值是10,您可以自己设置合理的合并因子的值来加快构造索引。

2、maxMergeDocs

合并因子mergeFactor是从segment优化性能入手,而maxMergeDocs,看命名就知道是从构成子索引(segment)的文档(document)着手提升性能。 maxMergeDocs参数决定写入内存索引文档(document)的个数,到达该数目后就把该内存索引写入硬盘,生成一个新的子索引segment文件,所以该参数也就相当于一个内存buffer,一般来说越大索引速度越快。

需要注意的是,maxBufferedDocs这个参数默认是disabled的,因为lucene中还用另外一个参数(RAMBufferSizeMB)控制这个bufffer的索引文档个数。其实maxBufferedDocs和RAMBufferSizeMB这两个参数是可以一起使用的,一起使用时只要有一个触发条件满足就写入硬盘,生成一个新的子索引segment文件。
 

            IndexWriter writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);Console.WriteLine(writer.GetMaxMergeDocs());//MaxMergeDocs默认值是2147483647 (也即int.MaxValue)writer.SetMaxMergeDocs(1024);Console.WriteLine(writer.GetMaxMergeDocs());//设置后,当前是1024

maxMergeDocs默认值是常量int.MaxValue(2147483647)。

3、RAMBufferSizeMB

如你所知,这个参数作用类似于maxMergeDocs,控制用于缓存索引文档的内存上限。如果buffer的索引文档个数到达该上限就写入硬盘。一般来说该参数越大,占用内存越大,索引速度也就越快。

            IndexWriter writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);Console.WriteLine(writer.GetRAMBufferSizeMB());//RAMBufferSizeMB默认值是16 writer.SetRAMBufferSizeMB(1024);Console.WriteLine(writer.GetRAMBufferSizeMB());//设置后,当前是1024

RAMBufferSizeMB默认值是16.

小结:通过上述分析说明,我们知道,合理设置三个参数的值,可以充分利用内存(理论上,参数值越大,内存利用越充分,但是必须和实际的机器性能相结合),避免频繁的IO操作,提升索引速度。

二、关于索引文件的几种常见格式

这里我主要参考了觉先的这一篇和这一篇非常耐心详细的两篇好文章。虽然收藏已久,但是直到现在自己还没有完全搞明白各个文件之间的关系。现在看来,依然醍醐灌顶很有收获。态度决定一切,有时间我会重新写一篇更详细透彻的学习笔记。下面重点记录一下对我自己的实际编程有帮助的几个文件格式。

1、.gen格式和segments_N

每个segment代表lucene的一个完整索引段,建立索引后必须存在的一个文件。一个索引(Index)可以同时存在多个segments_N。当我们要打开一个索引的时候,我们必须要选择一个segments_N文件来打开。在打开索引选择某个segments_N文件时,segments.gen文件和segments_N的N(Generation)的确定就有密切关系(具体逻辑可以参考这篇的4.1.1)。

2、.cfs格式

即复合索引文件格式。我们知道,索引的内容可能非常大,文件数量也可能非常多。如果遇到这种情况,系统打开文件的数量将很大,会极大地耗费系统资源。因此,lucene提供了一个单文件索引格式,也就是所谓的复合索引格式。使用复合索引格式存储Document内容时,只需要在初始化完成一个IndexWriter对象后,使用SetUseCompoundFile(boolean)方法,在设置UseCompoundFile为true后,就会有这个文件。

            IndexWriter writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);Console.WriteLine(writer.GetUseCompoundFile());//默认为truewriter.SetUseCompoundFile(false);Console.WriteLine(writer.GetUseCompoundFile());

默认情况下,IndexWriter将UseCompoundFile置为True。

 

3、.lock格式

顾名思义,.lock就是锁文件类型了。对于普通优化后的索引文件,这个锁文件是看不到的。当我们通过IndexWriter或者IndexModifier对索引文件进行插入、修改或者删除操作的时候,都会生成一个.lock的锁文件。在lucene旧版本的类库中,通过多线程进行索引更改等操作,很容易发生异常,通常情况下都是由于该锁文件。提到了锁机制,我们有必要了解一下lucene的并发性规则:

操作是否允许
对同一个索引运行多个并行的搜索进程
对一个正在生成、被优化或正在与另一索引合并的索引运行多个并行的搜索进程,或该索引正在进行删除、更新文档等操作时,对索引运行多个并行的搜索进程
对同一个索引用多个IndexWriter对象执行添加、更新文档的操作
当一个从索引中删除文档的IndexReader对象没有成功关闭时,打开一个IndexWriter对象用于在这个索引中添加新的文档
IndexWriter对象向索引中添加新文档后,未成功关闭;在此之后,打开一个IndexReader对象用于从这个索引中删除文档

我们可以看到这种并发性规则对于搜索是毫无限制的,但是索引的其他操作可能会对搜索产生影响,比如更新后还没有优化的索引可能影响搜索速度,搜索的准确性也不可靠。好在我们的实际项目中都会有一定的策略来使用索引,比如相同的索引复制两份,一份专门用来搜索,一份用来增删改和优化,然后定时切换。

3、.fnm格式

包含 Document中所有Field名称。

4、.fdx和.fdt格式

.fdt文件用于存储具有 Field.Store.YES属性的field的数据的相关信息。而.fdx类型文件则是一个索引,用于存储域的信息。

5、.tii和.tis格式

.tii存储分词后term的索引文件,标明了每个.tis文件中词条的位置。

6、deletable格式

在lucene的索引中,所有的文档被删除后并不是立刻从索引中去除,而是留待下次合并索引或对索引进行优化时才真正删除。这种功能是通过deletable文件实现的。所有的文档在被删除后,会首先在deletable文件中留一个记录,要真正删除时,才将索引除去。

最后附上一张流传于网上的简明图片说明一下常见的索引及其文件格式的关系:

lucene_file_format

其他参考文章:

http://lucene.apache.org/java/2_9_2/fileformats.html

转载于:https://www.cnblogs.com/jeffwongishandsome/archive/2011/02/11/lucenet-net-explanation.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/475759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android wsdl封装,《android 解析WebService》

android端解析WebService我采用的是ksoap来完成的。ksoap相对来说也是比较简单的。代码如下package com.lv.test;import org.ksoap2.SoapEnvelope;import org.ksoap2.serialization.SoapObject;import org.ksoap2.serialization.SoapSerializationEnvelope;import org.ksoap2.t…

LeetCode 638. 大礼包(无限背包DP)

1. 题目 在LeetCode商店中, 有许多在售的物品。 然而,也有一些大礼包,每个大礼包以优惠的价格捆绑销售一组物品。 现给定每个物品的价格,每个大礼包包含物品的清单,以及待购物品清单。请输出确切完成待购清单的最低…

在2008 server安装vm server时发生的错误error1718、error1335……

;转载于:https://www.cnblogs.com/minglog/archive/2011/02/15/1955290.html

keepass2Android密码,Keepass2Android密码管理(快速解锁密码)

Keepass2Android密码管理能帮助我们保存各类网站、应用的密码,大家提前设置好之后每次输入密码的时候只需要输入很少的字符就能快速解锁密码,为大家的日常使用提供方便。软件特色* 几乎可与所有的Android 的浏览器结合使用 (见下文)*快速解锁&#xff1a…

LeetCode 845. 数组中的最长山脉(中心扩展)

1. 题目 我们把数组 A 中符合下列属性的任意连续子数组 B 称为 “山脉”&#xff1a; B.length > 3存在 0 < i < B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B[i] > B[i1] > ... > B[B.length - 1] &#xff08;注意&#xff1a;B 可以是 A 的…

hibernate3.6.0日志配置

hibernate3 自带的默认的日志框架是slf4j&#xff0c;hibernate3的slf只是一个日志的接口&#xff0c;而hibernate3 自带默认的日志框架&#xff0c;在实际开发中很少有公司或者是项目中用到&#xff0c;这里记录一种使用log4j的日志框架来代替slf4j日志框架的实现&#xff0c;…

android stackview,Android StackView 使用示例

cell.xml 布局文件&#xff1a;xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/cellImage"android:layout_width"200dp"android:layout_height"200dp"/>主布局文件&#xff1a;android:id"id/activ…

LeetCode 1239. 串联字符串的最大长度(回溯/动态规划)

文章目录1. 题目2. 解题2.1 回溯超时解2.2 回溯优化2.3 动态规划1. 题目 给定一个字符串数组 arr&#xff0c;字符串 s 是将 arr 某一子序列字符串连接所得的字符串&#xff0c;如果 s 中的每一个字符都只出现过一次&#xff0c;那么它就是一个可行解。 请返回所有可行解 s 中…

android 伪造gps位置,在Android中使用GPS的假位置

您正在开发一个将设置坐标(经度和纬度)的应用程序.它必须显示我的位置,因为我在那个坐标.它类似于位置欺骗者.. http://www.androidzoom.com/android_applications/tools/location-spoofer_gkmc.html但我没有这样做..这是我的代码..请任何人帮助我.public class Mock extends M…

LeetCode 395. 至少有K个重复字符的最长子串(分治)

1. 题目 找到给定字符串&#xff08;由小写字符组成&#xff09;中的最长子串 T &#xff0c; 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。 示例 1: 输入: s "aaabb", k 3 输出: 3 最长子串为 "aaa" &#xff0c;其中 a 重复了 3 次。示…

WCF 体系结构图

转载于:https://www.cnblogs.com/agressivo/articles/1958858.html

android studio电影院选座,8排电影院选座最佳位置

8排电影院选座最佳位置在哪里呢&#xff1f;8排电影院属于小影厅&#xff0c;小影厅银幕宽度在10米以下&#xff0c;座位100以内&#xff0c;座位排数通常拥有8-14排&#xff0c;小影厅整体空间小&#xff0c;选座时要选中间稍靠后一些的位置。由于整体排数少&#xff0c;因此选…

LeetCode 1011. 在 D 天内送达包裹的能力(二分查找)

1. 题目 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。 传送带上的第 i 个包裹的重量为 weights[i]。每一天&#xff0c;我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。 返回能在 D 天内将传送带上的所有包裹送达的船的…

仿Jquery链式操作的xml操作类

经常需要对xml文件进行操作&#xff0c;参考了Jquery的链式操作后实现了xmlHelper类。代码usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Xml;namespaceConfigUpdate{ ///<summary>///调用非静态的操作方法的 ///</summary>publiccla…

4月17日鸿蒙开发者大会,4月17日这天,将载入华为史册

文/笨鸟原创不易&#xff0c;禁止抄袭、洗稿&#xff0c;违者必究&#xff01;万众瞩目的华为鸿蒙系统对于国人来说&#xff0c;一部智能手机只有实现了芯片和系统技术的自主化&#xff0c;才能被称之为真正的国产手机。而就目前的国内手机市场而言&#xff0c;除华为之外的所有…

LeetCode 875. 爱吃香蕉的珂珂(二分查找)

1. 题目 珂珂喜欢吃香蕉。这里有 N 堆香蕉&#xff0c;第 i 堆中有 piles[i] 根香蕉。警卫已经离开了&#xff0c;将在 H 小时后回来。 珂珂可以决定她吃香蕉的速度 K &#xff08;单位&#xff1a;根/小时&#xff09;。每个小时&#xff0c;她将会选择一堆香蕉&#xff0c;…

MsSql正反表达式

例子&#xff1a; UPDATE [Photo_Table] SET istopistop^1,IsTopDateTimegetdate() WHERE charindex(, rtrim(PHOTOID) , , , PHOTOIDLIST ,)>0转载于:https://www.cnblogs.com/yibinboy/archive/2011/02/22/1961675.html

LeetCode 1455. 检查单词是否为句中其他单词的前缀

1. 题目 给你一个字符串 sentence 作为句子并指定检索词为 searchWord &#xff0c;其中句子由若干用 单个空格 分隔的单词组成。 请你检查检索词 searchWord 是否为句子 sentence 中任意单词的前缀。 如果 searchWord 是某一个单词的前缀&#xff0c;则返回句子 sentence 中…

html怎么修改锚点的属性,在HTML中设置自定义锚点

我已经在帖子here和here中看到了这个话题,但它们并没有真正帮助我.情况非常相似&#xff1a;页面顶部的滚动页面和粘性菜单栏(固定div),锚点分散在长滚动文本中.像这样的HTML&#xff1a;Heading Foothis is some text, and a lot of it...jump to Heading Foo...Heading Blaan…

PHP输出Excel实例代码

这里使用PHPExcel的开源类 一个完整的实例&#xff1a; <?php require_once("../includes/function.php"); //提供了SQL注入检测函数inject_check require_once("../class/DB.php"); //DB操作类&#xff0c;自己扩展一下 $db new DB(); if($_GET[sho…