通过lucene索引建立的效率研究的方法
Boosting特性
luncene对Documen
t和Field提供了一个可以设
置的Boosting参数, 这个参数的用处是告诉lucen
e, 某些记录更重要,在搜索的时候优
先考虑他们 比如在搜索的时候你可能觉得几个
门户的网页要比垃圾小站更优先考
虑
lucene默认的boosting参数是1.0, 如果你觉得这个field重要,你可以把boosting设置为1.5, 1.2….等, 对Document设置boosting相当设定了它的每个Field的基准boosting,到时候实际Field的boosting就是(Document-boosting*Field-boosting)设置了一遍相同的boosting.
似乎在lucene的记分公式里面有boosting参数,不过我估计一般人是不会去研究他的公式的(复杂),而且公式也无法给出最佳值,所以我们所能做的只能是一点一点的改变boosting, 然后在实际检测中观察它对搜索结果起到多大的作用来调整
一般的情况下是没有必要使用boosting的, 因为搞不好你就把搜索给搞乱了, 另外如果是单独对Field来做Bossting, 也可以通过将这个Field提前来起到近似的效果
Indexing Date
日期是lucene需要特殊考虑
的地方之一, 因为我们可能需要对日期进行范围
搜索, Field.keyword(s
tring,Date)提供了这
样的方法,lucene会把这个
日期转换为string, 值得注意的是这里的日期是精确到
毫秒的,可能会有不必要的性能损
失, 所以我们也可以把日期自行转化为
YYYYMMDD这样的形势,就
不用精确到具体时间了,通过Fi
le.keyword(Stir
ng,String) 来index, 使用PrefixQuery 的YYYY一样能起到简化版的日
期范围搜索(小技巧), lucene提到他不能处理19
70年以前的时间,似乎是上一代
电脑系统遗留下来的毛病
Indexing 数字
-
如果数字只是简单的数据, 比如中国有56个民族. 那么可以简单的把它当字符处理
-
如果数字还包含数值的意义,比如价格, 我们会有范围搜索的需要(20元到30元之间的商品),那么我们必须做点小技巧, 比如把3,34,100 这三个数字转化为003,034,100 ,因为这样处理以后, 按照字符排序和按照数值排序是一样的,而lucene内部按照字符排序,003->034->100 NOT(100->3->34)
排序
Lucene默认按照相关度(s
core)排序,为了能支持其他
的排序方式,比如日期,我们在a
dd Field的时候,必须保证fi
eld被Index且不能被to
kenized(分词),并且排
序的只能是数字,日期,字符三种
类型之一
Lucene的IndexWriter调整
IndexWriter提供了一
些参数可供设置,列表如下
|
属性 |
默认值 |
说明 |
mergeFactor |
org.apache.lucene.mergeFactor |
10 |
控制index的大小和频率,两个作用 |
maxMergeDocs |
org.apache.lucene.maxMergeDocs |
Integer.MAX_VALUE |
限制一个段中的document数目 |
minMergeDocs |
org.apache.lucene.minMergeDocs |
10 |
缓存在内存中的document数目,超过他以后会写入到磁盘 |
maxFieldLength |
|
1000 |
一个Field中最大Term数目,超过部分忽略,不会index到field中,所以自然也就搜索不到 |
这些参数的的详细说明比较复杂:mergeFactor有双重作用
-
设置每mergeFactor个document写入一个段,比如每10个document写入一个段
-
设置每mergeFacotr个小段合并到一个大段,比如10个document的时候合并为1小段,以后有10个小段以后合并到一个大段,有10个大段以后再合并,实际的document数目会是mergeFactor的指数
简单的来说mergeFactor 越大,系统会用更多的内存,更少磁盘处理,如果要打批量的作index,那么把mergeFactor设置大没错, mergeFactor 小了以后, index数目也会增多,searhing的效率会降低, 但是mergeFactor增大一点一点,内存消耗会增大很多(指数关系),所以要留意不要”out of memory”
把maxMergeDocs设置小,可以强制让达到一定数量的document写为一个段,这样可以抵消部分mergeFactor的作用.
minMergeDocs相当于设置一个小的cache,第一个这个数目的document会留在内存里面,不写入磁盘。这些参数同样是没有最佳值的, 必须根据实际情况一点点调整。
maxFieldLength可以在任何时刻设置, 设置后,接下来的index的Field会按照新的length截取,之前已经index的部分不会改变。可以设置为Integer.MAX_VALUE
RAMDirectory 和 FSDirectory 转化
RAMDirectory(RA
MD)在效率上比FSDirec
tyr(FSD)高不少, 所以我们可以手动的把RAMD当
作FSD的buffer,这样就
不用去很费劲的调优FSD那么多
参数了,完全可以先用RAM跑好
了index, 周期性(或者是别的什么算法)来
回写道FSD中。 RAMD完全可以做FSD的bu
ffer。
为查询优化索引(index)
Indexwriter.opt
imize()方法可以为查询优
化索引(index),之前提到
的参数调优是为indexing
过程本身优化,而这里是为查询优
化,优化主要是减少index文
件数,这样让查询的时候少打开文
件,优化过程中,lucene会
拷贝旧的index再合并,合并
完成以后删除旧的index,所
以在此期间,磁盘占用增加, IO符合也会增加,在优化完成瞬
间,磁盘占用会是优化前的2倍,
在optimize过程中可以同
时作search。
并发操作Lucene和locking机制
-
所有只读操作都可以并发
-
在index被修改期间,所有只读操作都可以并发
-
对index修改操作不能并发,一个index只能被一个线程占用
-
index的优化,合并,添加都是修改操作
IndexWriter和IndexReader的实例可以被多线程共享,他们内部是实现了同步,所以外面使用不需要同步
Locing
lucence内部使用文件来l
ocking, 默认的locking文件放在j
ava.io.tmpdir,可
以通过-Dorg.apache
.lucene.lockDir
=xxx指定新的dir,有wr
ite.lock commit.lock两个文件
,lock文件用来防止并行操作
index,如果并行操作, lucene会抛出异常,可以通
过设置-DdisableLuc
eneLocks=true来禁
止locking,这样做一般来
说很危险,除非你有操作系统或者
物理级别的只读保证,比如把in
dex文件刻盘到CDROM上。
调试IndexWriter
IndexWriter 有一个infoStream的变
量,调试信息从这里输出。可以把
System.out设置给它