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

lucene3.0.3中的Spanquery和Spans介绍

阅读更多

      SpanQuery就是用来查询不仅仅是含有term,并且存在的各个term的位置符合一定条件的doc,从源码上讲他最大的改变就是有了getSpans(IndexReader reader)方法,该方法返回的是Spans,在SpanQuery中使用Spans这个类来召回doc(在普通的termQuery中是使用termDocs进行召回),我们先看看Spans这个类。

      在Spans的javadoc中有这样的说明:Spans用于枚举term出现的位置,如果是在一个document中则枚举在当前的doc中出现的各个位置,枚举完了当前的doc的所有的位置,则会读取下一个doc,这正是他的next()方法的意义,多次调用这个next方法可能会修改当前的docid(使用doc方法)也可能不会,因为当前的term在当前的doc中可能出现了多次。Spans还有一个方法start()用于获得当前的位置的开始位置(也就是在创建索引时的位置增量),还有end()方法,用于获得当前的位置的结束位置。getPayload()方法,该方法用于获得当前位置的payload,当然可能在建立索引的时候就没有保存词频和位置信息,所以还有一个开关——isPayloadAvailable()方法,他表示当前的位置能否读取payload。注意这里返回的是Collection<byte[]>类型的payload,这是因为可能有的Spans的子类(比如后面说的SpanNearQuery生成的Span,包含多个子Spans)会返回多个payload,所以用一个集合Collection,一个paylaod用byte[]表示。一句话总结下Spans:用于按照顺序枚举一个term在所有包含他的doc中的位置,可以读取payload。

 

       我们看一个最简单的SpanQuery——SpanTermQuery。

      SpanTermQuery其实本质上没有任何用处,他的作用也是按照term进行查找doc(和TermQuery是一个意思),只要一个doc含有指定的term就会被召回,没有任何其他的限制(和普通的termQuery的召回逻辑一样),我觉得它存在的意义仅仅是让我们接触一下SpanQuery。他有了区别于普通的termQuery的地方——使用termPositions而不是termDocs进行查找(体现在使用Spans而没有直接在query中使用Term),打分方式也发生了变化——计算tf与termQuery完全不一样;第二个意义是在他的基础上有一个PayLoadTermQuery,这个类可以使用payload进行打分。我们看一下SpanTermQuery的源码。

      先看一下他最关键的方法:getSpans方法:

@Override
public Spans getSpans(final IndexReader reader) throws IOException {
	return new TermSpans(reader.termPositions(term), term);//返回的是一个TermSpans
}

 我们看一下TermSpans,尤其关注其next方法:

 

public TermSpans(TermPositions positions, Term term) throws IOException {
	this.positions = positions;
	this.term = term;
	doc = -1;
}

 在构造方法中会传入一个termPositions,这个类是TermDocs的子类,他有一个额外功能是能读取prx文件,也就是能得到每一个term在每一个doc中的出现的位置以及在该位置上的payload,当然他也能读取倒排表,也就是能召回doc。我们看一下termSpan的next方法:

/**
 * 如果当前的term在当前的doc中的所有的出现位置读取完了(count==freq)则继续读取下一个doc,然后读取下一个位置,增加count++; 
 * 如果没有读取完,则仅仅读取下一个位置。
 * */
@Override
public boolean next() throws IOException {当前的doc的所有的位置都读取完了。
	if (count == freq) {//
		if (!positions.next()) {
			doc = Integer.MAX_VALUE;
			return false;
		}
		doc = positions.doc();
		freq = positions.freq();
		count = 0;
	}
	//读取下一个位置,此时一定返回true,因为当前的doc没有读取完。
	position = positions.nextPosition();
	count++;
	return true;
}

 这里的count表示在当前的doc上所有的出现的次数(用freq表示)中已经读取了多少次,如果已经读取完了当前的doc的所有的次数,则读取下一个doc,即进入if判断,否则继续读取当前的doc。

 

SpanTermQuery的weight以及scorer

      SpanTermQuery并没有改写createWeight方法,他会生成一个SpanWeight,这个类没有什么特殊的,他会继续生成一个SpanScorer用来回收doc和打分,重点看一下SpanScorer的nextDoc方法,因为这个方法用于回收doc,这个方法会调用setFreqCurrentDoc方法,

/**
 * 设置当前doc的freq,他是通过读取当前doc的多个位置来实现的。
 */
protected boolean setFreqCurrentDoc() throws IOException {
	if (!more) {
	        return false;
	}
	doc = spans.doc();//通过Spans获得当前的doc(当然spans是根据其封装的termPosition来实现的这个功能)
	freq = 0.0f;
	do {
		int matchLength = spans.end() - spans.start();
		freq += getSimilarity().sloppyFreq(matchLength);
		more = spans.next();
	} while (more && (doc == spans.doc()));//直到读取完当前doc上所有的position,所以尽管spans的next方法只会读取一个位置,但是在scorer里面试读取了一个完整的doc,并且每个位置都读取了,
	return true;
}	

 scorer利用spans了读取了一个完整的doc,并且根据出现的次数得出了freq的值,在score方法中就会使用这个值对当前的doc进行打分。

/**得分唯一不同的是计算tf发生了变化*/
@Override
public float score() throws IOException {
	float raw = getSimilarity().tf(freq) * value; // raw score
	return norms == null ? raw : raw * Similarity.decodeNorm(norms[doc]); // normalize
}

 

这样SpanTermQuery就完了,他也是根据term进行召回doc,只不过他是将倒排表(termDocs,在SpanQuery中是使用了TermPositions)封装在了Spans里面,使用spans来一个一个位置的读取,并且得分的计算方式发生了变化。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     

      

 

分享到:
评论

相关推荐

    lucene中的SpanQuery和PhraseQuery详解(有图示)

    Lucene中的SpanQuery和PhraseQuery详解 Lucene是一个功能强大的搜索引擎库,提供了多种查询方式,其中SpanQuery和PhraseQuery是两个重要的查询类型。本文将详细介绍SpanQuery和PhraseQuery的使用和区别。 一、...

    lucene-3.0.3-src.zip

    3. **搜索优化**:Lucene 3.0.3的源码中,可以看到对Boosting、Filtering和Sorting等高级搜索功能的实现,以及对TopDocs排序算法的优化。 四、实战应用 了解了Lucene的内部机制后,我们可以根据实际项目需求,结合...

    盘古分词、lucene3.0.3搜索的使用示例v1.3.zip

    《盘古分词与Lucene 3.0.3在.NET 4.0中的应用实践》 盘古分词和Lucene是两个在文本处理和信息检索领域中至关重要的工具。盘古分词,作为一款优秀的中文分词系统,能够高效准确地对中文文本进行分词,为后续的数据...

    lucene3.0.3搜索的使用示例

    这个"lucene3.0.3搜索的使用示例"压缩包文件很可能是为了帮助用户理解并学习如何在项目中应用Lucene 3.0.3版本的功能。 在Lucene 3.0.3中,主要包含了以下核心概念和知识点: 1. **索引(Indexing)**:这是Lucene...

    Lucene3.0.3+盘古分词 资源汇总

    《Lucene3.0.3与盘古分词:打造高效搜索引擎》 在信息技术日新月异的时代,搜索引擎已经成为我们获取信息的重要工具。Lucene,作为Apache软件基金会的一个开源项目,是Java语言实现的全文检索引擎库,为开发者提供...

    盘古分词、lucene3.0.3搜索的使用示例v1.2

    盘古分词和Lucene是两个在中文信息处理领域广泛应用的工具,本示例将详细介绍如何在.NET 4.0环境中整合这两个组件,以实现高效的全文搜索功能,并新增了分页功能,为开发者提供了更便捷的开发体验。 首先,盘古分词...

    盘古分词、lucene3.0.3搜索的使用示例.zip

    通过以上步骤,开发者可以在自己的.NET 4.0项目中实现基于盘古分词和Lucene 3.0.3的全文检索功能。这不仅提高了搜索效率,也为用户提供了更精准的搜索体验。在实际应用中,还可以结合其他技术,如缓存、分布式索引等...

    Lucene3.0.3+盘古分词(证实可用,可指定使用自己的词库文件).rar

    在“Lucene3.0.3+盘古分词(证实可用,可指定使用自己的词库文件).rar”这个压缩包中,包含了实现这一功能所需的DLL文件和词库文件,这使得开发者可以轻松地在自己的项目中集成这一功能。 首先,我们要明白Lucene ...

    lucene 3.0.3.core.jar

    lucene3.0.3.core.jar文件,不用到apache官方网站下载17M的包,直接下载这个core就可以了。

    Lucene 3.0.3 API

    在 Lucene 3.0.3 版本中,我们看到了一系列重要的特性和改进,这些都极大地提升了其性能和易用性。 1. **索引过程**:Lucene 的索引过程涉及到将文档内容转换为倒排索引,这是一种高效的存储和检索方式。在 3.0.3 ...

    lucene-3.0.3.zip

    在这个3.0.3版本中,它继续展现了其在信息检索领域的强大性能和灵活性。Lucene的主要目标是为开发者提供一个可嵌入到他们的应用中的、高效的全文检索引擎。这个版本的发布标志着Lucene在功能和稳定性上的进一步提升...

    Lucene3.0分词系统.doc

    Lucene3.0分词系统的核心在于理解和应用其分词原理,无论是对于英文还是中文文本,这一过程都是构建高效搜索引擎的基础。以下是对Lucene3.0分词系统中涉及的关键知识点的深入解析。 ### 英文分词原理 英文分词相较...

    Lucene.NET v3.0.3 DEMO范例程序(含PanGu分词)

    这是Lucene.NET v3.0.3 DEMO范例程序(含PanGu分词),用C#语言编写的,同时对PanGu分词进行了整合,可以直接下载运行。 项目中还整理了一个后台任务线程监听范例,可以用作增量索引创建,但这个需要你自行加入相关...

    Lucene.net3.0.3源码

    Apache Lucene.Net 3.0.3 just passed a vote for release - our first official release since graduating from the incubator in August. A lot of work was put into porting and testing the code. We've ...

    lucene-smartcn-3.0.3.jar

    lucene-smartcn-3.0.3.jar

    lucene源码和教程

    lucene3.0.3源码和教程

    Lucene SpellChecker3.0.2

    Lucene SpellChecker for Lucene 3.0.2

    Lucene实战(中文版第二版)对应Lucene版本

    《Lucene实战(中文版第二版)》是针对搜索引擎开发领域的经典著作,它详细介绍了如何使用Apache Lucene这个强大的全文搜索引擎库。Lucene是Java语言实现的开源项目,被广泛应用于各种信息检索系统中,包括网站搜索...

Global site tag (gtag.js) - Google Analytics