`
Rexwong
  • 浏览: 10523 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

lucene学习(一)——DocFieldProcessorPerThread中的processDocument方法

阅读更多

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;
		}
	}

 

分享到:
评论

相关推荐

    与lucene3.0兼容的庖丁jar包

    at org.apache.lucene.index.DocFieldProcessorPerThread.processDocument(DocFieldProcessorPerThread.java:246) at org.apache.lucene.index.DocumentsWriter.updateDocument(DocumentsWriter.java:774) at org...

    Lucene的的学习资料及案例

    Lucene是一个高性能、全文检索库,由Apache软件基金会开发并维护,是Java编程语言中广泛使用的搜索引擎库。它提供了一个简单的API,使得开发者能够方便地在应用中实现全文检索功能。本篇文章将围绕Lucene的核心概念...

    lucene学习资料收集

    【标题】:“Lucene学习资料收集” 【描述】:Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发。这个资料集可能包含了关于如何理解和使用Lucene的各种资源,特别是通过博主huanglz19871030在iteye上的...

    lucene学习lucene学习

    2. 创建索引:清单 1 展示了一个简单的 Java 示例,演示如何使用 Lucene 对一个目录中的 .txt 文件创建索引。在这个例子中,`fileDir` 指定包含待索引文本文件的目录,`indexDir` 是存储 Lucene 索引文件的位置。`...

    Lucene学习源码.rar

    本文将主要围绕Java Lucene进行深入探讨,并基于提供的“Lucene学习源码.rar”文件中的“Lucene视频教程_讲解部分源码”展开讨论。 一、Lucene核心概念 1. 文档(Document):Lucene中的基本单位,用于存储待检索...

    Java搜索工具——Lucene实例总结(一)

    Java搜索工具——Lucene实例总结(一) 在Java开发中,搜索引擎已经成为不可或缺的一部分,而Apache Lucene正是一个强大的全文搜索引擎库。这篇博文将带你深入理解Lucene的基本概念和使用方式,帮助你快速入门并掌握...

    lucene学习pdf2

    "lucene学习pdf2" 提供的文档,无疑是对Lucene深入理解的一把钥匙,它涵盖了Lucene的核心概念、操作流程以及高级特性。 首先,Lucene的基础知识是必不可少的。Lucene的核心在于索引和搜索,它将非结构化的文本数据...

    Lucene初试——关于大文本建立索引和中文乱码以及QueryParser检索的一些体会 - sheen口开河 - CSDN博客

    这主要是由于Lucene在内存中缓冲文档,直至达到一定的数量或内存限制,然后才将数据写入硬盘。为了解决这个问题,有以下几种策略: 1. **文本预处理**:将大文本分割成多个小文件,然后分别对每个小文件进行索引。 ...

    lucene学习资料

    《Lucene学习资料》 Lucene是一个开源的全文搜索引擎库,由Apache软件基金会维护。它提供了高级的文本分析和索引功能,使得开发者能够轻松地在应用程序中集成强大的搜索功能。这个资料包中的《Lucene in Action_2nd...

    Lucene-2.0学习文档

    通过调用`IndexWriter`的`addDocument()`方法,我们可以将文档添加到索引中,实现对文本内容的索引化。 接着,我们讨论`MyScoreDocComparator.java`。在Lucene中,搜索结果通常按照相关性排序,相关性由`ScoreDoc`...

    开发自己的搜索引擎——Lucene+Heritrix(第2版)_随书光盘.rar

    《开发自己的搜索引擎——Lucene+Heritrix(第2版)_随书光盘.rar》是一个包含资源的压缩包,主要用于帮助读者深入理解并实践搜索引擎的开发。Lucene和Heritrix是两个重要的开源工具,它们在构建搜索引擎的过程中起着...

    lucene学习-02

    在深入探讨“Lucene学习-02”这一主题之前,我们先来理解一下Lucene的核心概念。Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,广泛应用于各种搜索引擎和信息检索系统。它提供了文本分析、索引构建、...

    Lucene.net学习帮助文档

    总之,Lucene.net是一个强大的全文搜索引擎工具,通过深入学习其源码和相关文档,开发者可以构建出满足各种需求的搜索解决方案。无论你是.NET开发者还是对全文检索技术感兴趣,Lucene.net都是一个值得投入时间和精力...

    全文检索技术学习(三)——Lucene支持中文分词 - 李阿昀的博客 - CSDN博客1

    在全文检索技术中,Lucene 是一个非常重要的开源搜索引擎库,它提供了强大的文本分析和索引功能。在处理中文文本时,由于中文的特殊性,需要进行分词处理才能有效地进行搜索。本篇博客主要讨论了如何使用 Lucene ...

    lucene.NET 中文分词

    在Lucene.NET中,高亮显示搜索结果是一项常用功能,它可以帮助用户快速定位搜索关键词。高亮通常通过Highlighter类实现,以下是一般流程: 1. **创建Highlighter实例**:`var highlighter = new ...

    Lucene3.3.0学习Demo

    这个"Lucene3.3.0学习Demo"是针对这一版本进行的实践教学资源,旨在帮助开发者更好地理解和使用Lucene。 首先,我们来看看Lucene的基本工作流程: 1. **分词**:Lucene通过Analyzer处理输入的文本,将其分解为一...

Global site tag (gtag.js) - Google Analytics