一、简单认识索引
Lucene.Net的应用相对比较简单。一段时间以来,我最多只是在项目中写点代码,利用一下它的类库而已,对很多名词术语不是很清晰,甚至理解可能还有偏差。从我过去的博客你也可以看出,语言表达一直不是个人所长,就算”表达“了也有大面积抄书的嫌疑,所以很多概念性的介绍能省则省(除非特别有别要说明),希望有心的初学者注意,理清概念和辨别技术名词非常重要,请参考相关文档。
Lucene的索引由1或多个segment(片段)构成,一个segment由多个document构成,一个document又由1个或多个field构成,一个field又由一个或多个term构成。下面这张图可以说明一切:
从图中不难看出,Lucene的索引是一个由点到线,由线到面的组成结构,这一点我们可以通过查看Lucene生成的索引文件看出来。
二、创建、优化、删除和更新索引实践
备注:在解决方案所在文件夹中,有一个测试用的Resource文件夹,内有4个.txt文件。我在本地测试的时候,就使用了Resource下的四个文本文件。
1、索引保存至文件
(1)、创建索引
先初始化一个IndexModifier对象,然后执行创建索引的核心方法:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
最后,IndexModifier对象执行Close方法。
几个注意点:
a、IndexModifier类封装了平时经常使用的IndexWriter和IndexReader,而且不用我们额外考虑多线程;
b、StandardAnalyzer是经常使用的一个Analyzer,目前对中文分词支持的也还不错(大名鼎鼎的盘古分词请参考牛人eaglet的这几篇);
c、IndexModifier的Optimize方法的执行可以优化索引文件,但是比较耗时间,根据我的测试,索引文件越大,优化时间线性增加,所以实际的开发中这个方法我们都会按照一定的策略执行;
d、IndexModifier的Close方法必须执行,否则你所做的一切都是无用功。
(2)、按照id删除一条索引
代码相对而言非常简单,直接利用IndexModifier 的DeleteDocuents方法:
?
1 2 3 4 5 6 7 |
|
其中,IndexModifier还有一个方法DeleteDocument,它的参数是整数docNum,通常我们也不知道索引文件的内部docNum是多少,所以非常少用它。
(3)、按照id更新一条索引
贴一下主要方法:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
需要注意,这一次,我们使用了IndexWriter对象的UpdateDocument方法,而IndexModifier没有找到现成的UpdateDocument方法。Optimize通常需要执行一下,否则索引文件中会有两个相同id的索引。
2、索引保存至内存
如果1你已经理解了,2其实可以不用细究。在IndexModifier的构造函数里有一个重载:
?
1 | |
下面的示例代码中第一个参数RAMDirectory就是一个Directory,我们可以把它定义成静态,创建索引的时候就完成了保存至内存的效果:
?
1 2 | |
经测试,增删改查原理同1。
3、利用Lucene.Net配合数据库查询
平时开发中,对于数据库中的海量数据,频繁读库可能不能满足效率和速度的需求。我们也可以利用Lucene.Net配合数据库快速查询结果。至于如何对数据库利用Lucene.Net创建索引,增删改查和同1中的介绍是一模一样的。比如本文demo中创建索引的实现,取前1000个人对他们的Id和姓名进行索引。在编码之前,我先往Person表中插入了一些数据:
?
1 2 3 4 5 6 7 8 | |
接着先取出1000个人:
?
1 2 | |
然后建立索引即可:
?
1 2 3 4 5 6 7 8 9 10 11 | |
同样的道理,最后我们也执行这两个方法(Optimize方法不是一定要做的):
?
1 2 | |
三、搜索
本文示例代码中的搜索都是利用Lucene.Net的IndexSearcher默认的比较直接简单的一个搜索方法 Search(Query query, Filter filter, int n),很多重载方法我也没有使用过:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
|
下一篇我会补充介绍一下Lucene.Net常用的搜索、排序和分页,今天偷懒一下。
最后,本文demo中的代码算不上优美,可读性还凑合,希望大家下载之后看看吧,我还在幻想万一对新手能有所帮助,或者引来某个误入的高手指点一二,于人于己那就真是善莫大焉了。