DocFieldProcessorPerThread中的processDocument
/** Process the document. If there is
* something for this document to be done in docID order,
* you should encapsulate that as a
* DocumentsWriter.DocWriter and return it.
* DocumentsWriter then calls finish() on this object
* when it's its turn.
*/
public DocumentsWriter.DocWriter processDocument() throws IOException {
consumer.startDocument();
fieldsWriter.startDocument();
final Document doc = docState.doc;// 得到当前的document
assert docFieldProcessor.docWriter.writer
.testPoint("DocumentsWriter.ThreadState.init start");
fieldCount = 0;
final int thisFieldGen = fieldGen++;
final List<Fieldable> docFields = doc.getFields();// 得到Document中所有的Field
final int numDocFields = docFields.size();
// Absorb any new fields first seen in this document.
// Also absorb any changes to fields we had already
// seen before (eg suddenly turning on norms or
// vectors, etc.):
// 循环处理docment中的field。
for (int i = 0; i < numDocFields; i++) {
Fieldable field = docFields.get(i);
final String fieldName = field.name();
// Make sure we have a PerField allocated
// 得到field的name的hash值,通过hashMask得到hashPos
final int hashPos = fieldName.hashCode() & hashMask;
// fieldHash存放所以见过的fields的数组,而这个数据下标是和field的hash相关的
DocFieldProcessorPerField fp = fieldHash[hashPos];
// 循环fp,由此说明,fieldHash每一个元素是一个链表,类似于HashMap的存储机制。事实上
// 最终循环得到field
while (fp != null && !fp.fieldInfo.name.equals(fieldName))
fp = fp.next;
// 如果没有得到field就向fieldHash中添加一个field,否则更新
if (fp == null) {
// TODO FI: we need to genericize the "flags" that a
// field holds, and, how these flags are merged; it
// needs to be more "pluggable" such that if I want
// to have a new "thing" my Fields can do, I can
// easily add it
FieldInfo fi = fieldInfos.add(fieldName, field.isIndexed(),
field.isTermVectorStored(), field
.isStorePositionWithTermVector(), field
.isStoreOffsetWithTermVector(), field
.getOmitNorms(), false, field
.getOmitTermFreqAndPositions());
fp = new DocFieldProcessorPerField(this, fi);
fp.next = fieldHash[hashPos];
fieldHash[hashPos] = fp;
// 由于fieldHash元素是一个链表,totalFieldCount并不是field的个数,而是当前fieldHash已有元素个数
totalFieldCount++;
if (totalFieldCount >= fieldHash.length / 2)// 扩容,确保fieldHash长度是已有元素的两倍(为什么要是两倍呢?)
rehash();
} else
fp.fieldInfo.update(field.isIndexed(), field
.isTermVectorStored(), field
.isStorePositionWithTermVector(), field
.isStoreOffsetWithTermVector(), field.getOmitNorms(),
false, field.getOmitTermFreqAndPositions());
//将当前field存入fields
if (thisFieldGen != fp.lastGen) {
// First time we're seeing this field for this doc
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;//fields[]存放当前doc
fp.lastGen = thisFieldGen;
}
if (fp.fieldCount == fp.fields.length) {
Fieldable[] newArray = new Fieldable[fp.fields.length * 2];
System.arraycopy(fp.fields, 0, newArray, 0, fp.fieldCount);
fp.fields = newArray;
}
fp.fields[fp.fieldCount++] = field;
if (field.isStored()) {
fieldsWriter.addField(field, fp.fieldInfo);
}
}
// If we are writing vectors then we must visit
// fields in sorted order so they are written in
// sorted order. TODO: we actually only need to
// sort the subset of fields that have vectors
// enabled; we could save [small amount of] CPU
// here.
quickSort(fields, 0, fieldCount - 1);
for (int i = 0; i < fieldCount; i++)
fields[i].consumer.processFields(fields[i].fields,
fields[i].fieldCount);
if (docState.maxTermPrefix != null && docState.infoStream != null)
docState.infoStream
.println("WARNING: document contains at least one immense term (longer than the max length "
+ DocumentsWriter.MAX_TERM_LENGTH
+ "), all of which were skipped. Please correct the analyzer to not produce such terms. The prefix of the first immense term is: '"
+ docState.maxTermPrefix + "...'");
final DocumentsWriter.DocWriter one = fieldsWriter.finishDocument();
final DocumentsWriter.DocWriter two = consumer.finishDocument();
if (one == null) {
return two;
} else if (two == null) {
return one;
} else {
PerDoc both = getPerDoc();
both.docID = docState.docID;
assert one.docID == docState.docID;
assert two.docID == docState.docID;
both.one = one;
both.two = two;
return both;
}
}
分享到:
相关推荐
at org.apache.lucene.index.DocFieldProcessorPerThread.processDocument(DocFieldProcessorPerThread.java:246) at org.apache.lucene.index.DocumentsWriter.updateDocument(DocumentsWriter.java:774) at org...
Lucene是一个高性能、全文检索库,由Apache软件基金会开发并维护,是Java编程语言中广泛使用的搜索引擎库。它提供了一个简单的API,使得开发者能够方便地在应用中实现全文检索功能。本篇文章将围绕Lucene的核心概念...
【标题】:“Lucene学习资料收集” 【描述】:Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发。这个资料集可能包含了关于如何理解和使用Lucene的各种资源,特别是通过博主huanglz19871030在iteye上的...
2. 创建索引:清单 1 展示了一个简单的 Java 示例,演示如何使用 Lucene 对一个目录中的 .txt 文件创建索引。在这个例子中,`fileDir` 指定包含待索引文本文件的目录,`indexDir` 是存储 Lucene 索引文件的位置。`...
本文将主要围绕Java Lucene进行深入探讨,并基于提供的“Lucene学习源码.rar”文件中的“Lucene视频教程_讲解部分源码”展开讨论。 一、Lucene核心概念 1. 文档(Document):Lucene中的基本单位,用于存储待检索...
Java搜索工具——Lucene实例总结(一) 在Java开发中,搜索引擎已经成为不可或缺的一部分,而Apache Lucene正是一个强大的全文搜索引擎库。这篇博文将带你深入理解Lucene的基本概念和使用方式,帮助你快速入门并掌握...
"lucene学习pdf2" 提供的文档,无疑是对Lucene深入理解的一把钥匙,它涵盖了Lucene的核心概念、操作流程以及高级特性。 首先,Lucene的基础知识是必不可少的。Lucene的核心在于索引和搜索,它将非结构化的文本数据...
这主要是由于Lucene在内存中缓冲文档,直至达到一定的数量或内存限制,然后才将数据写入硬盘。为了解决这个问题,有以下几种策略: 1. **文本预处理**:将大文本分割成多个小文件,然后分别对每个小文件进行索引。 ...
《Lucene学习资料》 Lucene是一个开源的全文搜索引擎库,由Apache软件基金会维护。它提供了高级的文本分析和索引功能,使得开发者能够轻松地在应用程序中集成强大的搜索功能。这个资料包中的《Lucene in Action_2nd...
通过调用`IndexWriter`的`addDocument()`方法,我们可以将文档添加到索引中,实现对文本内容的索引化。 接着,我们讨论`MyScoreDocComparator.java`。在Lucene中,搜索结果通常按照相关性排序,相关性由`ScoreDoc`...
《开发自己的搜索引擎——Lucene+Heritrix(第2版)_随书光盘.rar》是一个包含资源的压缩包,主要用于帮助读者深入理解并实践搜索引擎的开发。Lucene和Heritrix是两个重要的开源工具,它们在构建搜索引擎的过程中起着...
在深入探讨“Lucene学习-02”这一主题之前,我们先来理解一下Lucene的核心概念。Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,广泛应用于各种搜索引擎和信息检索系统。它提供了文本分析、索引构建、...
总之,Lucene.net是一个强大的全文搜索引擎工具,通过深入学习其源码和相关文档,开发者可以构建出满足各种需求的搜索解决方案。无论你是.NET开发者还是对全文检索技术感兴趣,Lucene.net都是一个值得投入时间和精力...
在全文检索技术中,Lucene 是一个非常重要的开源搜索引擎库,它提供了强大的文本分析和索引功能。在处理中文文本时,由于中文的特殊性,需要进行分词处理才能有效地进行搜索。本篇博客主要讨论了如何使用 Lucene ...
在Lucene.NET中,高亮显示搜索结果是一项常用功能,它可以帮助用户快速定位搜索关键词。高亮通常通过Highlighter类实现,以下是一般流程: 1. **创建Highlighter实例**:`var highlighter = new ...
这个"Lucene3.3.0学习Demo"是针对这一版本进行的实践教学资源,旨在帮助开发者更好地理解和使用Lucene。 首先,我们来看看Lucene的基本工作流程: 1. **分词**:Lucene通过Analyzer处理输入的文本,将其分解为一...