转载请务必注明,原创地址,谢谢配合!
http://qindongliang1922.iteye.com/blog/2013702
今天散仙来谈下有关在Lucene中,如何完成一个搜索的过程,用过Lucene的朋友都会经常用到如下的一段代码:
Query query=parser.parse(searchText);//解析构建query树
TopDocs td=search.search(query, 100);//检索的入口,限制返回结果集100
ScoreDoc[] sd=td.scoreDocs;//加载所有的Documnet文档
以上的代码,可能是我们基本的检索中用得最多的一段了,但事实上,除了最基础的检索外,search方法,还有大量极其丰富的重载方法,API方法如下:
TopDocs search(Query query, int n);
TopDocs search(Query query, Filter filter, int n);
TopFieldDocs search(Query query, int n,Sort sort);
void search(Query query, Filter filter, Collector results);
void search(Query query, Collector results);
TopFieldDocs search(Query query, Filter filter, int n,Sort sort);
TopFieldDocs search(Query query, Filter filter, int n, Sort sort, boolean doDocScores, boolean doMaxScore);
//以下是lucene支持的深度分页检索方式
TopDocs searchAfter(ScoreDoc after, Query query, Filter filter, int n, Sort sort);
TopDocs searchAfter(ScoreDoc after, Query query, int n, Sort sort);
TopDocs searchAfter(ScoreDoc after, Query query, Filter filter, int n, Sort sort, boolean doDocScores, boolean doMaxScore);
那么lucene是如何组织并执行这些重载的参数,如filter,collector,sort,以及topN和最终的打分呢?
下面我们详细看下这个流程是如何进行的.
1,首先一段文本将会被当成关键词进行检索,在这之前会由QueryParser这个类进行语法解析,经过分词解析后关键词会被QueryParser这个类组装成一个BooleanQuery对象,里面可能涵盖了多种经过解析后生成的Query对象,从而构成了一颗query树,这也是QueryParser这个类的功能强大之处,支持各种交,并,补,查,模糊,通配,范围,距离等等一系列简化写法。
整个检索在水平方向上主要有3个类完成即Query,Weight, Scorer,其各自的用处是,Quer负责生成组织查询对象,Weight负责计算权重,Score负责打分,垂直方向上依靠BooleanQuery构成的一颗树结构,其非叶子节点就是BooleanQuery,叶子节点是其他Query,形成Query后,Weight对象的组织就依靠Query树递归一步一步构建起来的,Scorer也是类似的。
2,第二步就开是进行检索了,跟踪源码我们发现,如果在search方法里的filter的值不为null的情况下,那么第一件事就是使用FilteredQuery包装原来的Query,过滤掉在检索不需要的结果集 Filter中有个重要的方法getDocIdSet,这个方法过滤对应的文档,然后将结果集返回,当然我们也可以自定义filter来实现其他一些额外的功能。
3,第三步,就开始使用上一步过滤后的Query对象,首先,重写Query树。重写的主要目的是将整棵树上一些需要改变搜索关键词的地方重新改变。比如,整个索引建立时有这样几个term,"算法","算术",在搜索"算*"时QueryParser将其解释为PrefixQuery,在重写这步便会搜索所有前缀为"算"的term,并用ConstantScoreQuery替换掉原来的PrefixQuery,在ConstantScorer中会将"算*"替换为"算法", "算术"两个实际的term,进而转化成求解一般term评分,这是典型的将复杂问题转换成已知问题求解的思想。
然后,通过代码Weight weight = query.createWeight(this);
根据Query树创建Weight树,这个创建过程是一个递归的过程。调用顶层query.createWeight,就会将整棵Weight树构建起来,接着
计算ValueForNormalization,然后根据ValueForNormalization计算queryNorm
,接着计算公共部分打分公式。
接下来通过TopScoreDocCollector collector = TopScoreDocCollector.create(nDocs, after, !weight.scoresDocsOutOfOrder());
这行代码,查询文档数topN,会被用于创建符合n以内的collector,
然后会遍历基于段对象的List<AtomicReaderContext> leaves,集合,来收集每个原子reader中符合条件的信息,接着就会由Weight对象,生成Score对象
Scorer scorer = weight.scorer(ctx, !collector.acceptsDocsOutOfOrder(), true, ctx.reader().getLiveDocs());
在这步中,会根据具体情况生个多个XXXWeight对象,最基本的是TermWeight对象,然后再生成XXXWeight对应的XXXScore对象,
最后再调用 scorer.score(collector);方法遍历所有结果文档,并将结果集保存在一个优先级队列里面,并排序,topN参数,会被初始化成这个队列的大小。
FieldValueHitQueue<Entry> queue = FieldValueHitQueue.create(sort.fields, numHits);
关于排序的具体实现,也是通过类似Comparator和Comparatorable这样灵活高效的关系完成的。
在scorer方法的里,也加入了similarity来影响评分,similarity的默认实现类
DefaultSimilarity更是让我们控制评分方便多了,通常情况下我们只需要重写这个类,加入自己的评分逻辑,就可以在结果集中,影响评分。
最后从collector中拿到最终的TopDocs,至此一个完成的检索流程就结束了,当然我们
拿到TopDocs后,就可以为我们的业务做各种显示和处理了。
最后简单总结一下各个步骤的顺序:
步骤 | 描述 |
一 | 首先根据检索文本生成query树 |
二 | 如果有filter的话,会先执行filter过滤我们需要的文档集合 |
三 | 创建Weight和Scorer,并通过Scorer.score()进行评分 |
四 | 最后在队列里进行排序,默认是按照相关性得分排序 |
转载请务必注明,原创地址,谢谢配合!
http://qindongliang1922.iteye.com/blog/2013702
分享到:
相关推荐
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会...
11.Lucene搜索深入实战进阶1 共4页 12.Lucene搜索深入实战进阶2 共9页 13.Lucene搜索深入实战进阶3 共5页 14.Lucene搜索深入实战进阶4 共5页 15.Lucene高级进阶1 共23页 16.Lucene高级进阶2 共4页 17.Lucene高级进阶...
11.Lucene搜索深入实战进阶1 共4页 12.Lucene搜索深入实战进阶2 共9页 13.Lucene搜索深入实战进阶3 共5页 14.Lucene搜索深入实战进阶4 共5页 15.Lucene高级进阶1 共23页 16.Lucene高级进阶2 共4页 17.Lucene高级进阶...
11.Lucene搜索深入实战进阶1 共4页 12.Lucene搜索深入实战进阶2 共9页 13.Lucene搜索深入实战进阶3 共5页 14.Lucene搜索深入实战进阶4 共5页 15.Lucene高级进阶1 共23页 16.Lucene高级进阶2 共4页 17.Lucene高级进阶...
lucene4.3增删改查的的一个工具类,对新手来说是一份不可多得的入门资料。
lucene高级搜索进阶项目_04
全文检索lucene 4.3 所用到的3个jar包,包含lucene-queryparser-4.3.0.jar、 lucene-core-4.3.0.jar、lucene-analyzers-common-4.3.0.jar。
lucene4.3 按坐标距离排序,里面写了个简单的例子。运行就行
本课程由浅入深的介绍了Lucene4的发展历史,开发环境搭建,分析lucene4的中文分词原理,深入讲了lucenne4的系统架构,分析lucene4索引实现原理及性能优化,了解关于lucene4的搜索算法优化及利用java结合lucene4实现...
lucene4.3源代码 censed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information ...
结合笔者的实际开发经验,总结了一些新的开发技巧和开发思路,并对网上流传的一些错误...本书既可为零起点的Lucene初学者提供系统全面的学习指导,也可帮助有相关经验的开发者解决在开发过程中遇到的一些难题和疑惑。
11.Lucene搜索深入实战进阶1 共4页 12.Lucene搜索深入实战进阶2 共9页 13.Lucene搜索深入实战进阶3 共5页 14.Lucene搜索深入实战进阶4 共5页 15.Lucene高级进阶1 共23页 16.Lucene高级进阶2 共4页 17.Lucene高级进阶...
11.Lucene搜索深入实战进阶1 共4页 12.Lucene搜索深入实战进阶2 共9页 13.Lucene搜索深入实战进阶3 共5页 14.Lucene搜索深入实战进阶4 共5页 15.Lucene高级进阶1 共23页 16.Lucene高级进阶2 共4页 17.Lucene高级进阶...
11.Lucene搜索深入实战进阶1 共4页 12.Lucene搜索深入实战进阶2 共9页 13.Lucene搜索深入实战进阶3 共5页 14.Lucene搜索深入实战进阶4 共5页 15.Lucene高级进阶1 共23页 16.Lucene高级进阶2 共4页 17.Lucene高级进阶...
使用lucene需要检索时,需要导入jar包,下载全资源文件,进去找就可以
1.XunTa是在lucene4.3上创建的通过“知识点”来找人的搜人引擎。 输入一个关键词(或组合),XunTa返回一个排名列表,排在前面的人是与该关键词(组合)最相关的“达人”。 可访问 http://www.xunta.so立即体验...
lucene高级搜索进阶项目_03
Lucene搜索引擎开发进阶实战----高清版 Lucene搜索引擎开发进阶实战----高清版
11.Lucene搜索深入实战进阶1 共4页 12.Lucene搜索深入实战进阶2 共9页 13.Lucene搜索深入实战进阶3 共5页 14.Lucene搜索深入实战进阶4 共5页 15.Lucene高级进阶1 共23页 16.Lucene高级进阶2 共4页 17.Lucene高级进阶...
11.Lucene搜索深入实战进阶1 共4页 12.Lucene搜索深入实战进阶2 共9页 13.Lucene搜索深入实战进阶3 共5页 14.Lucene搜索深入实战进阶4 共5页 15.Lucene高级进阶1 共23页 16.Lucene高级进阶2 共4页 17.Lucene高级进阶...