博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucene的索引过程,非常简洁,
阅读量:4187 次
发布时间:2019-05-26

本文共 3724 字,大约阅读时间需要 12 分钟。

Lucene的索引过程,非常简洁,我们只需要调用Lucene提供的几个API方法即可,看似简单的过程,其实在lucene的内部,是非常复杂巧妙的,只不过它给我们提供的外部API非常精简轻便。
Java代码 复制代码 收藏代码
1.Directory directory=FSDirectory.open(new File("E:\\1111111111111111111\\1\\"));//打开存放索引的路径
2. IndexWriter writer1=new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_45, new IKAnalyzer(true)));
3. Document doc=new Document();
4. doc.add(new StringField("id", "11", Store.YES));
5. doc.add(new StringField("name","三劫散仙", Store.YES));
6. writer1.addDocument(doc);
7.
8. writer1.forceMerge(1);//优压缩段
9. writer1.commit();//提交数据
如上所示,就是一个索引的基本流程。当然上面的这个流程显的太简单了。而真正的情况可能要比这个复杂的多。
Lucene的索引过程主要分为3个主要的步骤:
1:将原始文档转换为文本
2:使用分词器分析文本
3:将分析好的文本保存到索引里。
当然,如果我们的应用是基于垂直搜索的,可能我们的数据源就是我们的数据库,或者是一些例如excel,word,pdf,txt之类的文件,如果是文件的话我们可以使用Apache Tika来解析文本,然后在分词后存入索引,但是Lucene是不直接具备这样的功能的,需要我们提前自己把数据的文本内容抽取出来。
当我们把我们所需要的文本抽取出来之后,下一步就开始分析我们的索引内容了,当然这个过程是非常复杂的,不过只需要提前设置好分词器就可以方便的完整这个过程,为什么要分词呢?
我们都知道lucene是基于倒排索引的形式,来构建整个索引的,把原来的根据一篇文章查找关键词,变成了根据关键词查找文章,这样一个反转,类似,书本的页码一样,就能够非常高效的检索了,在分析过程中,lucene会对一些token,做净化,清洗,归一,以及去掉一些禁用词等等,这个过程都是由Analyzer来完成的。当处理好最终的token时,我们就可以使用IndexWriter对象来把数据添加到磁盘的索引里,为以后的检索做准备。
下面我们来详细介绍下分词的过程,一般情况下分词指的是将Lucene中的Field文本,转换为最基本的索引表示单元,也就是term,分词器对分析操作进行了一系列的封装通过Tokenizer和一些TokenFilter,执行若干操作,将文本转换成便于索引查找的语汇单元。
这些操作可能包括:提取文本关键词,去除标点符号,去掉音调符号(拼音和英文),转换大小写,去除常用词,将单词还原成词干,或者将单词转为基本形式,词形归并,或者我们还需要在分词的过程中注入同义词等等。
文本中的每个语汇单元,都携带了一个文本值和其他的一些元数据信息,除了自身的文本值(即文本本身),还有原始文本从起点到终点的偏移量,语汇单元的类型,位置增量,标志位,和载荷。
注意起点的偏移量指的是语汇单元文本的的起始字符在原始文本中的位置,终点的偏移量指的是语汇单元终止字符的下一个位置,这一点需要注意并不是语汇单元的最后一个字符的位置,是其的下一位,偏移量在一些距离和跨度查询时非常有用,最重要的是这个偏移量对于搜索结果中的高亮显示非常有用,没有这些数据想完成高亮可能就有点麻烦了,但不是说不能完成,我们也可以在前台进行高亮,关于如何在前台高亮,可以参考散仙
修真篇的文章
在这里就不多涉及了。
当所有的文本被语汇成单元后,lucene将会通过一种链式方式,在后台层层把这些信息添加到lucene的各个索引文件里。默认的索引链在DocumentsWriterPerThread中有初始化
Java代码 复制代码 收藏代码
1.[static final IndexingChain defaultIndexingChain = new IndexingChain() {
2.
3. @Override
4. DocConsumer getChain(DocumentsWriterPerThread documentsWriterPerThread) {
5. /*
6. This is the current indexing chain:
7.
8. DocConsumer / DocConsumerPerThread
9. --> code: DocFieldProcessor
10. --> DocFieldConsumer / DocFieldConsumerPerField
11. --> code: DocFieldConsumers / DocFieldConsumersPerField
12. --> code: DocInverter / DocInverterPerField
13. --> InvertedDocConsumer / InvertedDocConsumerPerField
14. --> code: TermsHash / TermsHashPerField
15. --> TermsHashConsumer / TermsHashConsumerPerField
16. --> code: FreqProxTermsWriter / FreqProxTermsWriterPerField
17. --> code: TermVectorsTermsWriter / TermVectorsTermsWriterPerField
18. --> InvertedDocEndConsumer / InvertedDocConsumerPerField
19. --> code: NormsConsumer / NormsConsumerPerField
20. --> StoredFieldsConsumer
21. --> TwoStoredFieldConsumers
22. -> code: StoredFieldsProcessor
23. -> code: DocValuesProcessor
24. */
25.
26. // Build up indexing chain:
27.
28. final TermsHashConsumer termVectorsWriter = new TermVectorsConsumer(documentsWriterPerThread);
29. final TermsHashConsumer freqProxWriter = new FreqProxTermsWriter();
30.
31. final InvertedDocConsumer termsHash = new TermsHash(documentsWriterPerThread, freqProxWriter, true,
32. new TermsHash(documentsWriterPerThread, termVectorsWriter, false, null));
33. final NormsConsumer normsWriter = new NormsConsumer();
34. final DocInverter docInverter = new DocInverter(documentsWriterPerThread.docState, termsHash, normsWriter);
35. final StoredFieldsConsumer storedFields = new TwoStoredFieldsConsumers(
36. new StoredFieldsProcessor(documentsWriterPerThread),
37. new DocValuesProcessor(documentsWriterPerThread.bytesUsed));
38. return new DocFieldProcessor(documentsWriterPerThread, docInverter, storedFields);
39. }
40. };
经过一系列链式传递后,索引并不会马上写入磁盘中,而是先写入内存中,然后到一定时机会flush到磁盘上,这实际上也是一种优化策略,从而避免了频繁访问磁盘带来的IO开销,当然我们也可以显式得调用commit方法,将其刷新到磁盘上。

转载地址:http://cwnoi.baihongyu.com/

你可能感兴趣的文章
IT 2007预言
查看>>
怎样让.Net2.0的Membership使用已存在的Sql Server2000/2005数据库
查看>>
ASP.NET2.0 文本编辑器FCKeditor使用方法详解
查看>>
常见的 Web 项目转换问题及解决方案
查看>>
VS2005中使用ClickOnce 部署应用程序的升级
查看>>
Visual Studio2005下配置及运行NUnit
查看>>
最新版FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用简解
查看>>
.NET Framework 3.0框架慨述
查看>>
怎样用VS2005进行三层结构应用程序的开发
查看>>
知道自己获得MVP今天很高兴
查看>>
VS.NET2005安装部署之实战
查看>>
ASP.NET AJAX 之服务器端页面流程
查看>>
.Net服务组件(ServicedComponent)简介及其使用
查看>>
如何检测Remote Objects是否部署成功
查看>>
socket异步处理问题
查看>>
.Net Remoting中Remote Server的Port占用/释放问题
查看>>
信道、接收器、接收链和信道接受提供程序
查看>>
.Net Remoting配置文件的用法
查看>>
mscorwks.dll在DotNet中的地位以及在.Net代码保护方面的应用
查看>>
DotNet资源站点汇总
查看>>