`
guoyunsky
  • 浏览: 859026 次
  • 性别: Icon_minigender_1
  • 来自: 上海
博客专栏
3d3a22a0-f00f-3227-8d03-d2bbe672af75
Heritrix源码分析
浏览量:207190
Group-logo
SQL的MapReduce...
浏览量:0
社区版块
存档分类
最新评论

Lucene3.0源码分析(三) Lucene对多个Term查询的结果取交集算法

阅读更多

       本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/724989

      欢迎加入Heritrix群(QQ):109148319

 

      当查询 "Java AND Lucene" 的时候,需要对Java跟Lucene这个两个Term的查询结果取交集,也就是对查询到他们的DocumentID取交集,然后对获取到交集的DocumentID,根据评分,获得评分前N的DocumentID(至于Lucene获得评分前N的DocumentID算法,我请查看我这篇博客:Lucene3.0源码分析(二) Lucene中获得评分前N的DocumentID算法

),最终获得这些DocumentID的数据返回给用户。

       我这里模仿Lucene中的算法,具体请看一下Java代码以及注释,同时这些Java代码不依赖Lucene任何组件,可以单独运行。

      

import java.util.Arrays;
/**
 * 对有序数组取交集,数组必须按照从小到大排序
 * 模仿Lucene的合并子查询条件结果集
 * 
 * @author Administrator
 *
 */
public class MyConjunctionScorer {
	private MyScorer[] scorers=new MyScorer[2];
	private int length;		// 子评分器个数
	private int first=0;	// 迭代子评分器的起始指针位置
	private int last=-1;	// 迭代子评分器的终止指针位置
	
	private boolean more;	// 是否还有子查询条件以及里面是否还有DocumentID
	private boolean hasInit;// 是否已经初始化	
	
	public MyConjunctionScorer() {
		
	}
	
	/**
	 * 添加子查询条件评分器
	 * 
	 * @param scorer
	 */
	public void add(MyScorer scorer){
		needExpansion();
		length++;
		last++;
		scorers[last]=scorer;	
	}
	
	public boolean next(){
		if(!hasInit){	//首先初始化
			init();
			hasInit=true;
		}else if(more){
			more=scorers[last].next();	//获得下一个要匹配的数据,也就是上一次获取的结果数据的下一个数据
		}
		return doNext();
		
	}
	
	public int doc(){
		return scorers[first].doc;	//返回交集documentID
	}
	
	public boolean doNext(){
		while(more&&scorers[first].doc<scorers[last].doc){	//如果要比较的子查询条件评分器的DocumentID一直比last的DocumentID小则一直迭代
			more=scorers[first].SkipTo(scorers[last].doc);	// 从first中找到比last大的DocumentID
			last=first;										// 则以first为基准跟其他子评分器查询条件进行比较
			first=(first==length-1)?0:first+1;				// 指针后移,获得其他子查询条件评分器跟last指针位置的子查询条件评分器进行对比
		}
		return more;
	}
	
	/**
	 * 初始化
	 */
	public void init(){
		more=length>0;
		for(int i=0,pos=first;i<length;i++){
			if(!more){
				break;
			}
			more=scorers[pos].next();//获取子查询条件评分器下一个DocumentID,有的话返回true,没有的话则false
			pos=(pos==length-1)?0:pos+1;	//位置叠加,让每个子查询条件评分器可以进行迭代
		}
		if(more){	//如果每个子查询条件评分器里有DocumentID
			sortScorers();	//先对每个子查询条件评分器根据当前的DocumentID进行排序
		}
	}
	
	/**
	 * 排序
	 */
	public void sortScorers(){
		needExpansion();		//是否要扩容
		Arrays.sort(scorers);	//排序
	}
	
	/**
	 * 扩容
	 */
	public void needExpansion(){
		if(length>=scorers.length){
			MyScorer[] tmpScorers=new MyScorer[scorers.length*2];
			System.arraycopy(scorers, 0, tmpScorers,0,length);
			scorers=tmpScorers;
			
		}
	}
	
	public static void main(String[] args){
		int[] s1={3,4,5,6,7,8,9};
		int[] s2={2,3,9};
		int[] s3={3,4,5,9};
		
		MyScorer sc1=new MyScorer(s1);
		MyScorer sc2=new MyScorer(s2);
		MyScorer sc3=new MyScorer(s3);
		
		MyConjunctionScorer conScorer=new MyConjunctionScorer();
		conScorer.add(sc1);
		conScorer.add(sc2);
		conScorer.add(sc3);
		
		while(conScorer.next()){
			System.out.println(conScorer.doc());
		}
		
		
	}
}

 

/**
 * 模仿Lucene的TermScorer(子查询条件评分器)
 * 
 * @author Administrator
 *
 */
public class MyScorer implements Comparable{
	
	private int[] docs;		//所有DocumentID
	public int doc;			//当前DocumentID
	private int pointer;	//当前指针
	private int pointerMax;	//所允许的最大范围
	
	/**
	 * 获得当前指针位置
	 * @return
	 */
	public int getPointer() {
		return pointer;
	}
	
	/**
	 * 比较两个MyScorer大小,通过当前DocumentID进行比较
	 */
	@Override
	public int compareTo(Object arg0) {
		if(arg0 instanceof MyScorer){
			MyScorer s=(MyScorer)arg0;
			return this.doc-s.doc;
		}
		return 0;
	}
	
	public MyScorer(int[] docs) {
		super();
		this.docs = docs;
		doc=-1;
		pointer=-1;
		pointerMax=docs.length;
	}
	
	/**
	 * 获取下一个DocumentID
	 * @return
	 */
	public boolean next(){
		pointer++;
		if(pointer>=pointerMax){
			pointer=0;
			return false;
		}
		doc=docs[pointer];
		return true;
	}
	
	/**
	 * 指针跳转到大于或等于目标documentID值,然后接下来可以通过指针位置获取该值
	 * @param target
	 * @return
	 */
	public boolean SkipTo(int target){
		for(pointer++;pointer<pointerMax;pointer++){
			if(docs[pointer]>=target){
				doc=docs[pointer];
				return true;
			}
		}
		return false;
	}
	
	
}

 

更多技术文章、感悟、分享、勾搭,请用微信扫描:

分享到:
评论
1 楼 linliangyi2007 2010-11-11  
这个算法很不错,可以略作修改后,进行分布式的翻页查询,更深入的说,是一种mapreduce的实现基础

相关推荐

    lucene3.0 lucene3.0

    lucene3.0 lucene3.0 lucene3.0 lucene3.0 lucene3.0

    Lucene3.0之查询类型详解

    在Lucene3.0中,查询处理是一个关键环节,涉及多种查询方式和理论模型。以下是对这些概念的详细解释: 1. **查询方式**: - **顺序查询**:是最简单的查询方式,直接遍历索引,效率较低。 - **索引查询**:基于预...

    Lucene 3.0 原理与代码分析完整版

    《Lucene 3.0 原理与代码分析完整版》是一本深入解析Lucene 3.0搜索引擎库的专业书籍。Lucene是Apache软件基金会的开源项目,它为Java开发者提供了一个高性能、全文检索的工具包,广泛应用于各种信息检索系统。这...

    lucene 3.0 API 中文帮助文档 chm

    lucene 3.0 API中文帮助,学习的人懂得的

    lucene3.0核心jar包

    这里的"lucene3.0核心jar包"是 Lucene 的一个重要版本,发布于2009年,为当时的开发人员提供了构建全文搜索引擎的基础框架。 在 Lucene 3.0 中,以下几个关键知识点值得关注: 1. **索引结构**:Lucene 使用倒排...

    Lucene3.0 使 用 教 程

    【Lucene3.0 使用教程】是针对Java开发者的一个指南,旨在教授如何利用Apache Lucene 3.0.1版本实现全文检索功能。Lucene是一个高性能、可伸缩的开源全文检索库,它提供了文本分析、索引创建、文档检索等核心功能。...

    Lucene3.0全文信息检索

    4. **查询性能提升**:通过引入更智能的缓存机制,以及对查询执行路径的优化,使得复杂查询的响应时间缩短。 5. **增强的分析器**:Analyzer在3.0中有了更多可定制的选项,可以更好地处理各种语言和文本格式,支持...

    lucene3.0资料包

    用户可以在多个字段上同时进行搜索,Lucene3.0支持多字段查询,允许用户指定不同字段的权重,以实现更精准的匹配。 8. **内存缓存**: 为了提升性能,Lucene3.0引入了各种缓存机制,如字段值缓存、位集缓存等,...

    lucene3.0庖丁+索引搜索程序

    Lucene3.0是Apache软件基金会的一个项目,它是Java语言实现的全文检索引擎,提供了高性能、可扩展的搜索和分析功能。Lucene的核心包括索引构建、倒排索引、查询解析和结果排序等关键部分。3.0版本相比之前的版本,在...

    lucene3源码分析

    ### Lucene3源码分析知识点概述 #### 一、全文检索的基本原理 ##### 1....以上是对Lucene3源码分析的一些关键知识点总结,通过对这些概念和技术的理解,可以更好地掌握Lucene的工作原理及其应用。

    lucene3.0 分词器

    lucene3.0 中文分词器, 庖丁解牛

    lucene3.0-highlighter.jar

    lucene3.0-highlighter.jar lucene3.0的高亮jar包,从lucene3.0源码中导出来的

    lucene3.0 实例

    在这个实例中,我们将探讨如何在 JDK 1.5 和 Lucene 3.0 的环境下构建和运行一个简单的搜索引擎。 首先,Lucene 的核心概念包括文档(Document)、字段(Field)、索引(Index)和搜索(Search)。文档是存储信息的...

    lucene 2.0 api以及lucene 3.0 api

    总的来说,从 Lucene 2.0 进化到 3.0,主要变化在于性能提升、查询功能增强以及对更多场景的支持,这些改进使得 Lucene 成为了更加成熟和全面的全文搜索解决方案。学习并掌握这两个版本的 API,对于从事相关开发工作...

    基于lucene3.0 书籍查询系统

    4. **结果排名(Result Ranking)**:根据查询的相关度算法(如TF-IDF)对搜索结果进行排序。 5. **结果展示(Result Display)**:将排名后的搜索结果返回给用户,通常包括书名、作者、摘要等信息。 **三、系统...

    lucene3.0使用介绍及实例

    这个简单的示例展示了Lucene的基本用法,实际应用中可以根据需要扩展,例如添加更多的文档字段、实现更复杂的查询逻辑,或者使用硬盘目录替代内存目录进行持久化存储。 通过学习和实践,开发者可以利用Lucene 3.0的...

    lucene3.0 search

    2. 匹配评分(Scoring):Lucene使用TF-IDF(Term Frequency-Inverse Document Frequency)算法计算每个文档与查询的相关性,得分越高,相关性越强。 3. 排序与剪枝(Ranking and Pruning):根据评分对匹配的文档...

Global site tag (gtag.js) - Google Analytics