DocFieldProcessor类的任务
1 按顺序存储所有的field和对应的fieldinfo
2 为当前这篇doc的field按照fieldname来建立hash索引
3 调用InvertedDocConsumer类(抽象),对field的内容分词和建立内存索引
DocFieldProcessor类主要用到的其他类
DocFieldProcessorPerField类的对象负责存放一个fieldinfo和其对应的field(可能是多个,他们的fieldinfo相同),next成员可以指向下一个DocFieldProcessorPerField类对象,构成链表(用于解决fieldhash冲突)
DocInverterPerField是DocFieldProcessorPerField内用到的类,负责解析同一个fieldinfo里的field,建立索引
final class DocFieldProcessor extends DocConsumer {

  final DocFieldConsumer consumer;
final StoredFieldsConsumer storedConsumer;
final Codec codec; // 存储doc里所有的DocFieldProcessorPerField(这个类里面会存放多个fieldinfo相同的field),位置按顺序存储,一个位置里面放一个
DocFieldProcessorPerField[] fields = new DocFieldProcessorPerField[1];
int fieldCount; // 存储doc里所有的DocFieldProcessorPerField(这个类里面会存放多个fieldinfo相同的field),位置按fieldname的hash来存放,一个位置可能匹配多个,以链表结构存放
DocFieldProcessorPerField[] fieldHash = new DocFieldProcessorPerField[2];
int hashMask = 1;
int totalFieldCount; int fieldGen;
//浅拷贝 要分析的doument
final DocumentsWriterPerThread.DocState docState; final Counter bytesUsed;

DocFieldProcessor ::processDocument(FieldInfos.Builder fieldInfos)是DocFieldProcessor类主要功能的实现函数

  public void processDocument(FieldInfos.Builder fieldInfos) throws IOException {

    consumer.startDocument();
storedConsumer.startDocument(); fieldCount = 0; final int thisFieldGen = fieldGen++; //循环doc里的field,合并同fieldinfo的field进入一个DocFieldProcessorPerField,并且如果此轮循环有新创建的DocFieldProcessorPerField对象,则加入到顺序数组和hash数组里面
for(IndexableField field : docState.doc) {
final String fieldName = field.name(); //计算fieldname在hash数组里对应的位置
final int hashPos = fieldName.hashCode() & hashMask; DocFieldProcessorPerField fp = fieldHash[hashPos];
//查找对应位置下fieldname符合当前field的DocFieldProcessorPerField对象
while(fp != null && !fp.fieldInfo.name.equals(fieldName)) {
fp = fp.next;
} if (fp == null) {
//表示该fieldinfo是第一次出现,把field的info信息添加到fieldinfos里面,并且创建对应的fieldinfo对象
FieldInfo fi = fieldInfos.addOrUpdate(fieldName, field.fieldType());
//创建一个DocFieldProcessorPerField
fp = new DocFieldProcessorPerField(this, fi); //加入到hash链表里面
fp.next = fieldHash[hashPos];
fieldHash[hashPos] = fp;
totalFieldCount++; //hash表快满了,重新做hash
if (totalFieldCount >= fieldHash.length/2) {
rehash();
}
} else {
//更新fieldinfo对象
FieldInfo fi = fieldInfos.addOrUpdate(fieldName, field.fieldType());
assert fi == fp.fieldInfo : "should only have updated an existing FieldInfo instance";
} if (thisFieldGen != fp.lastGen) {
//说明这个fieldinfo是第一次出现,即本次循环new了DocFieldProcessorPerField
fp.fieldCount = 0; //判断顺序数组是不是满了
if (fieldCount == fields.length) {
final int newSize = fields.length*2;
DocFieldProcessorPerField newArray[] = new DocFieldProcessorPerField[newSize];
System.arraycopy(fields, 0, newArray, 0, fieldCount);
fields = newArray;
} fields[fieldCount++] = fp;
fp.lastGen = thisFieldGen;
}
//把field加入到fp中,同fieldinfo的field会加入到同一个fp里面
fp.addField(field); storedConsumer.addField(docState.docID, field, fp.fieldInfo);
}
//遍历顺序数组里的DocFieldProcessorPerField,调用DocInverterPerField对其里面的field进行分词建立索引之类的操作
ArrayUtil.introSort(fields, 0, fieldCount, fieldsComp);
for(int i=0;i<fieldCount;i++) {
final DocFieldProcessorPerField perField = fields[i];
perField.consumer.processFields(perField.fields, perField.fieldCount);
}
}

Lucene的DocFieldProcessor类的更多相关文章

  1. lucene.net helper类 【结合盘古分词进行搜索的小例子(分页功能)】

      转自:http://blog.csdn.net/pukuimin1226/article/details/17558247 添加:2013-12-25 更新:2013-12-26 新增分页功能. ...

  2. Lucene的Query类介绍

    把Lucene的查询当成sql的查询,也许会笼统的明白些query的真相了. 查询分为大致两类,1:精准查询.2,模糊查询. 创建测试数据. private Directory directory; ...

  3. 全文检索解决方案(lucene工具类以及sphinx相关资料)

    介绍两种全文检索的技术. 1.  lucene+ 中文分词(IK) 关于lucene的原理,在这里可以得到很好的学习. http://www.blogjava.net/zhyiwww/archive/ ...

  4. lucene 基础知识点

    部分知识点的梳理,参考<lucene实战>及网络资料 1.基本概念 lucence 可以认为分为两大组件: 1)索引组件 a.内容获取:即将原始的内容材料,可以是数据库.网站(爬虫).文本 ...

  5. lucene全文检索---打酱油的日子

    检索内容,一般的程序员第一时间想到的是sql的like来做模糊查询,其实这样的搜索是比较耗时的.已经有lucene帮我们 封装好了,lucene采用的是分词检索等策略. 1.lucene中的类描述 I ...

  6. 【转载】Lucene.Net入门教程及示例

    本人看到这篇非常不错的Lucene.Net入门基础教程,就转载分享一下给大家来学习,希望大家在工作实践中可以用到. 一.简单的例子 //索引Private void Index(){    Index ...

  7. Lucene.net站内搜索—3、最简单搜索引擎代码

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  8. 通过lucene的StandardAnalyzer分析器来了解分词

    本文转载http://blog.csdn.net/jspamd/article/details/8194919 不同的Lucene分析器Analyzer,它对TokenStream进行分词的方法是不同 ...

  9. Lucene 基础理论 (zhuan)

    http://www.blogjava.net/hoojo/archive/2012/09/06/387140.html**************************************** ...

随机推荐

  1. Linux_搜文件

    Linux 下搜文件, 通常先用 whereis 或 locate ,如果找不到,才以 find 搜寻!因为 whereis 与 locate 是利用数据库来搜寻数据,省时间! <<鸟哥的 ...

  2. 硬盘类型和Linux的分区

    目前硬盘主要分为以下几种:IDE,SCSI,SATA,SAS.其中SAS(Serial Attached SCSI)即串行连接SCSI,属于SCSI的新一代技术. 以下是Linux常见设备的名称: 装 ...

  3. Mapreduce读取Hbase表,写数据到多个Hbase表中

    Job端的变化: 通过设置conf,配置输出表,在reduce中获取输出表名字 Configuration conf = job.getConfiguration(); //输出表1 conf.set ...

  4. vmware下ubuntu14.04调整分辨率

    很多人在vmware中安装ubuntu时,为了调整屏幕分辨率,都去下载并安装vmware-tools.其实,这是没有必要的.如果你需要vmware和宿主机实现共享,或者为了使文件能拖进拖出,再或者是需 ...

  5. springMVC的详细步骤配置

    使用springMVC也可以代替struts2,当然只是代替业务分发的功能,struts2的一些其他功能它是没有的,不然要struts2有什么用. 下面我用springMVC代替struts2去整合h ...

  6. nodejs cmd

    引入系统模块 var exec = require('child_process').exec; cmd.js var exec = require('child_process').exec; va ...

  7. [POJ] #1002# 487-3279 : 桶排序/字典树(Trie树)/快速排序

    一. 题目 487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 274040   Accepted: 48891 ...

  8. NLP初步

    [NLP初步] NLP是Natural Lanuage Process的缩写.搜索引擎可以通过关词匹配和完成很多的任务, 比如话题搜索(搜索包含律师, 法院, 控告等词的文档), 但是搜索引擎无法理解 ...

  9. [原创]Devexpress XtraReports 系列 6 创建并排报表

    昨天我们已经介绍了如何创建交叉报表,详见:[原创]Devexpress XtraReports 系列 5 创建交叉报表 今天我们继续我们的XtraReports系列.Demo和数据库文件最后会附上. ...

  10. HDU 1564 Play a game (找规律博弈)

    Play a game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...