前言:目前自己在做使用 Lucene.net 和 PanGu 分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移。因为项目整体要迁移到 ASP.NET Core 2.0 版本, 而 Lucene 使用的版本是 3.6.0 ,PanGu 分词也是对应 Lucene3.6.0 版本的。不过好在 Lucene.net 已经有了 Core 2.0 版本(4.8.0 bate 版),而 PanGu 分词,目前有人正在做,貌似已经做完,只是还没有测试~,Lucene 升级的改变我都会加粗表示。
Lucene.net 4.8.0
https://github.com/apache/lucenenetPanGu 分词
https://github.com/LonghronShen/Lucene.Net.Analysis.PanGu/tree/netcore2.0Lucene.net 4.8.0 和之前的 Lucene.net 3.6.0 改动还是相当多的,这里对自己开发过程遇到的问题,做一个记录吧,希望可以帮到和我一样需要升级 Lucene.net 的人。我也是第一次接触 Lucene , 也希望可以帮助初学 Lucene 的同学。
IndexWriter 是用来创建和维护索引的。IndexWriter 的创建:在 Lucene4.8.0 中,创建 IndexWriter 对象,需要用到 IndexWriterConfig 参数,IndexWriterConfig 用来设置一些 IndexWriter 的属性:
- IndexWriterConfig _indexWriterConfig = new IndexWriterConfig(Lucene.Net.Util.LuceneVersion.LUCENE_48,analyze)
- IndexWriter _indexWriter = new IndexWriter(dir,_indexWriterConfig)
上面的代码创建了一个基本的 IndexWriter 对象,每个基本 IndexWriter 都必须有两个必要的属性:1. 操作的索引目录 dir ;2. 分词器 analyze . 这里要注意,IndexWriter 的分词器和 IndexSearch 的分词器应该是相同的,否则将会影响搜索结果。
我们通过 IndexWriterConfig 可以设置 IndexWriter 的属性,已达到我们希望构建索引的需求,这里举一些属性,这些属性可以影响到 IndexWriter 写入索引的速度:
- IndexWriterConfig.setRAMBufferSizeMB(double);
- IndexWriterConfig.setMaxBufferedDocs(int);
- IndexWriterConfig.setMergePolicy(MergePolicy)
setRAMBufferSizeMB() 是设置,当 IndexWriter 添加的文档的大小超过 RAMBufferSizeMB ,IndexWriter 就会把在内存中的操作,写入到硬盘中。具体一点:IndexWriter 在执行 AddDocuments(写入文档),DeleteDocuments(删除文档),UpdateDocuments(更新文档),这些操作的时候,这些操作都会先缓冲到内存中,也就是说执行完这些函数,其实储存的索引目录下是没有任何改变的,当 AddDocuments 的容量超过上述的属性的时候,这些操作才会具体执行到储存索引的硬盘当中。默认的
- DEFAULT_RAM_BUFFER_SIZE_MB 是16MB.
setMaxBufferedDocs() 是设置,当 IndexWriter 添加的文档数量超过 MaxBufferedDocs 的时候,IndexWriter 就会把内存中写入的文档,写到硬盘中,并生成一个新的索引文件 segment。关于 Lucene 的索引结构会在下面说到。
setMergePolicy 是设置索引合并的策略,MergePolicy 中有一个参数 DEFAULT_MAX_CFS_SEGMENT_SIZE 表示索引中最多有多少个 segment 文件。
上面提到了三个 IndexWriterConfig 的三个属性。我们知道,IndexWriter 是当缓存中的容量达到一定的限制条件之后,才开始将缓存中的操作写入到硬盘中,事实上,如果我们把限制条件定的值越大,索引的速度是越快的。显而易见,如果设置 RAMBufferSizeMB 和 MAXBufferedDocu 越大,IndexWriter 写入硬盘的次数就越少,而写索引的时间耗费大多在对硬盘的操作之上。
IndexWriter 写入索引之后,在索引目录里会有很多 segment 文件。segment 文件数量达到 MergeFactor (设置合并因子) 的时候,IndexWriter 会将这些 segment 文件合并,形成一个新的 segment 文件,类似于压缩。而在索引目录中,如果 segment 文件越多,则搜索的速度会降低,segement 文件越少,搜索的速度也就越快。所以当我们设置 MergeFactor 的值越大的时候,搜索的速度就会越快,而合并 segement 的速度则会降低,也即索引的速度会降低。
这是,一个索引目录下的索引文件。结构是这样的:
上面的图片中,只有一个段,_v6.fdt ;_v6.fdx ....... 都属于_v6 segment 中的内容。而 segments_5u 和 segments.gen 是段的元数据文件,也即它们保存了段的属性信息。
上面的是正向信息,还有反向信息就不详细说了。
在 Lucene 中 IndexWriter.Optimize 用来优化索引,而在 Lucene4.8.0 中 Optimize 已经更名为 ForceMerge,为的是少让你使用。IndexWriter 的优化实际上就是把 Segment 文件进行合并,你可以输入参数,ForceMerge(segments) 表示,合并到索引目录里最多有 segments 个段文件。而当参数越小的时候,也即合并的文件越多的时候,消耗的时间和空间就越大。很显然,合并是为了让我们的搜索速度变的更快。
在优化的过程中,需要当前索引容量两倍的空间,比如你现在的索引大小是 40 个 G,在优化过程中,索引的大小会增加到 80 多个 G,然后再合并直到最后只有 30 多个 G。当你的索引更新不是特别频繁的时候,可以优化一下,如果更新特别频繁,那么调用 ForceMerge 就会效率很低,这个时候,我们可以设置上面提到过的 MergeFactor 来,让索引中 segments 文件少一些。
1.IndexWriter 在操作一个索引的时候会创建一个锁定文件, Writer.lock 。如果有另一个 IndexWriter 要打开这个目录,将会报错。
2.IndexWriter 实例是完全线程安全的,多个线程可以同时调用它的任何方法.
来源: https://www.cnblogs.com/dacc123/p/8228298.html