Lucene的DocFieldProcessor类
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类的更多相关文章
- lucene.net helper类 【结合盘古分词进行搜索的小例子(分页功能)】
转自:http://blog.csdn.net/pukuimin1226/article/details/17558247 添加:2013-12-25 更新:2013-12-26 新增分页功能. ...
- Lucene的Query类介绍
把Lucene的查询当成sql的查询,也许会笼统的明白些query的真相了. 查询分为大致两类,1:精准查询.2,模糊查询. 创建测试数据. private Directory directory; ...
- 全文检索解决方案(lucene工具类以及sphinx相关资料)
介绍两种全文检索的技术. 1. lucene+ 中文分词(IK) 关于lucene的原理,在这里可以得到很好的学习. http://www.blogjava.net/zhyiwww/archive/ ...
- lucene 基础知识点
部分知识点的梳理,参考<lucene实战>及网络资料 1.基本概念 lucence 可以认为分为两大组件: 1)索引组件 a.内容获取:即将原始的内容材料,可以是数据库.网站(爬虫).文本 ...
- lucene全文检索---打酱油的日子
检索内容,一般的程序员第一时间想到的是sql的like来做模糊查询,其实这样的搜索是比较耗时的.已经有lucene帮我们 封装好了,lucene采用的是分词检索等策略. 1.lucene中的类描述 I ...
- 【转载】Lucene.Net入门教程及示例
本人看到这篇非常不错的Lucene.Net入门基础教程,就转载分享一下给大家来学习,希望大家在工作实践中可以用到. 一.简单的例子 //索引Private void Index(){ Index ...
- Lucene.net站内搜索—3、最简单搜索引擎代码
目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...
- 通过lucene的StandardAnalyzer分析器来了解分词
本文转载http://blog.csdn.net/jspamd/article/details/8194919 不同的Lucene分析器Analyzer,它对TokenStream进行分词的方法是不同 ...
- Lucene 基础理论 (zhuan)
http://www.blogjava.net/hoojo/archive/2012/09/06/387140.html**************************************** ...
随机推荐
- Android 订阅-发布者模式-详解
1.概念简述 Android 简称观察者模式, GoF说道:Observer模式的意图是“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”. 有 ...
- jsp界面项目绝对路径问题
方法一:直接采用绝对路径 (不推荐) 在JSP页面端,获得本项目的绝对地址(如果你的项目叫MyApp,那么获得到的地址就是 http://localhost:8080/MyApp/): 代码如下: & ...
- x-debug配置简述 - chunyu
一 x-debug 是什么?在配置之前,先解决一个问题,x-debug 是什么?我也不查标准答案了,就说说个人理解.x-debug是一个PHP调试工具,帮助开发者在IDE里面进行代码的断点调试,效果如 ...
- C常用字符字符串处理函数
1.strtok();字符串分片函数
- 转】使用kaptcha生成验证码
原博文出自于: http://www.cnblogs.com/xdp-gacl/p/4221848.html 感谢! kaptcha是一个简单好用的验证码生成工具,通过配置,可以自己定义验证码大小.颜 ...
- ArcGIS Desktop10.2与CityEngine2012兼容问题
要培训ArcGIS Desktop和Esri CityEngine2012.在一台机器上装好Desktop10.2之后,在注册Esri CityEngine2012时报出了"7019:Inv ...
- Wicket Hello World Example
A simple hello world example in Wicket, show the basic structure of Wicket web application. Tools an ...
- Ubuntu下Android编译环境的配置
从安装操作系统到编译程序结束,过程大致如下. 1. Ubuntu Linux操作系统安装软件包.使用 Ubuntu 14.04 Desktop系统.安装Linux系统到VMWare虚拟机上. 2. 完 ...
- Qt Creator无法用“UTF-8”编码解码
在Qt Creator 里打开其他编辑器的代码时有时会提示: 无法用"UTF-8"编码解码 在文件上右键使用NotePad++编辑器打开: 选择->格式-&g ...
- Tomcat 系统架构与设计模式,第 1 部分: 工作原理(转载)
简介: 这个分为两个部分的系列文章将研究 Apache Tomcat 的系统架构以及其运用的很多经典设计模式.本文是第 1 部分,将主要从 Tomcat 如何分发请求.如何处理多用户同时请求,还有它的 ...