18lucene学习总结之七:lucene搜索过程解析(3)内容摘要:
anQueryRewrite采取方式二,其 rewrite函数代码如下: public Query rewrite(IndexReader reader, MultiTermQuery query) throws IOException { //得到 MultiTermQuery的 Term枚举器 FilteredTermEnum enumerator = (reader)。 BooleanQuery result = new BooleanQuery(true)。 int count = 0。 try { //一个循环,取出对应 MultiTermQuery的所有的 Term,加入 BooleanQuery do { Term t = ()。 if (t != null) { TermQuery tq = new TermQuery(t)。 (() * ())。 (tq, )。 count++。 } } while (())。 } finally { ()。 } (count)。 return result。 } 以上两种方式各有优劣: o 方式一使得 MultiTermQuery对应的所有的 Term看成一个 Term,组成一个docid set,作为统一的倒排表参与倒排表的合并,这样无论这样的 Term在索引中有多少,都只会有一个倒排表参与合并,不会产生 TooManyClauses异常,也使得性能得到提高。 但是多个 Term之间的 tf, idf等差别将被忽略,所以采用方式二的 RewriteMethod为 ConstantScoreXXX,也即除了用户指定的 Query boost,其他的打分计算全部忽略。 o 方式二使得整个 Query对象树被展开,叶子节点都为 TermQuery,MultiTermQuery中的多个 Term可根据在索引中的 tf, idf等参与打分计算,然而我们事先并不知道索引中和 MultiTermQuery相对应的 Term到底有多少个,因而会出现 TooManyClauses异常,也即一个 BooleanQuery中的子查询太多。 这样会造成要合并的倒排表非常多,从而影响性能。 o Lucene认为对于 MultiTermQuery这种查询,打分计算忽略是很合理的,因为当用户输入 appl*的时候,他并不知道索引中有什么与此相关,也并不偏爱其中之一,因而计算这些词之间 的差别对用户来讲是没有意义的。 从而Lucene对方式二也提供了 ConstantScoreXXX,来提高搜索过程的性能,从后面的例子来看,会影响文档打分,在实际的系统应用中,还是存在问题的。 o 为了兼顾上述两种方式, Lucene提供了 ConstantScoreAutoRewrite,来根据不同的情况,选择不同的方式。 : public Query rewrite(IndexReader reader, MultiTermQuery query) throws IOException { final CollectionTerm pendingTerms = new ArrayListTerm()。 //计算文档数目限制, docCountPercent默认为 ,也即索引文档总数的 % final int docCountCutoff = (int) ((docCountPercent / 100.) * ())。 //计算 Term数目限制,默认为 350 final int termCountLimit = ((), termCountCutoff)。 int docVisitCount = 0。 FilteredTermEnum enumerator = (reader)。 try { //一个循环,取出与 MultiTermQuery相关的所有的 Term。 while(true) { Term t = ()。 if (t != null) { (t)。 docVisitCount += (t)。 } //如果 Term数目超限,或者文档数目超限,则可能非常影响倒排表合并的性能,因而选用方式一,也即 ConstantScoreFilterRewrite的方式 if (() = termCountLimit || docVisitCount = docCountCutoff) { Query result = new ConstantScoreQuery(new MultiTermQueryWrapperFilterMultiTermQuery(query))。 (())。 return result。 } else if (!()) { //如果 Term数目不太多,而且文档数 目也不太多,不会影响倒排表合并的性能,因而选用 方式二,也即 ConstantScoreBooleanQueryRewrite的方式。 BooleanQuery bq = new BooleanQuery(true)。 for (final Term term: pendingTerms) { TermQuery tq = new TermQuery(term)。 (tq, )。 } Query result = new ConstantScoreQuery(new QueryWrapperFilter(bq))。 (())。 (())。 return result。 } } } finally { ()。 } } 从上面的叙述中,我们知道,在重写 Query对象树的时候,从 MultiTermQuery得到的TermEnum很重要,能够得到对应 MultiTermQuery的所有的 Term,这是怎么做的的呢。 MultiTermQuery的 getEnum返回的是 FilteredTermEnum,它有两个成员变量,其中 TermEnum actualEnum是用来枚举索引中所有的 Term的,而 Term currentTerm指向的是当前满足条件的 Term, FilteredTermEnum的 next()函数如下: public boolean next() throws IOException { if (actualEnum == null) return false。 currentTerm = null。 //不断得到下一个索引中的 Term while (currentTerm == null) { if (endEnum()) return false。 if (()) { Term term = ()。 //如果当前索引中的 Term满足条件,则赋值为当前的 Term if (termCompare(term)) { currentTerm = term。 return true。 } } else return false。 } currentTerm = null。 return false。 } 不同的 MultiTermQuery的 termCompare不同: 对于 PrefixQuery的 getEnum(IndexReader reader)得到的是 PrefixTermEnum,其 termCompare实现如下: protected boolean termCompare(Term term) { //只要前缀相同,就满足条件 if (() == () amp。 amp。 ().startsWith(())){ return true。 } endEnum = true。 return false。 } 对于 FuzzyQuery的 getEnum得到的是 FuzzyTermEnum,其 termCompare实现如下: protected final boolean termCompare(Term term) { //对于 FuzzyQuery,其 prefix设为空 ,也即这一条件一定满足,只要计算的是 similarity if (field == () amp。 amp。 ().startsWith(prefix)) { final String target = ().substring(())。 = similarity(target)。 return (similarity minimumSimilarity)。 } endEnum = true。 return false。 } //计算 Levenshtein distance 也即 edit distance,对于两个字符串,从一个转换成为另一个所需要的最少基本操作 (添加,删除,替换 )数。 private synchronized final float similarity(final String target) { final int m = ()。 final int n = ()。 // init matrix d for (int i = 0。 i=n。 ++i) { p[i] = i。 } // start puting edit distance for (int j = 1。 j=m。 ++j) { // iterates through target int bestPossibleEditDistance = m。 final char t_j = (j1)。 // jth character of t d[0] = j。 for (int i=1。 i=n。 ++i) { // iterates through text // minimum of cell to the left+1, to the top+1, diagonally left and up +(0|1) if (t_j != (i1)) { d[i] = ((d[i1], p[i]), p[i1]) + 1。 } else { d[i] = ((d[i1]+1, p[i]+1), p[i1])。 } bestPossibleEditDistance = (bestPossibleEditDistance, d[i])。 }。18lucene学习总结之七:lucene搜索过程解析(3)
相关推荐
作出了巨大的努力,取得了一定的成绩 ,为我国 生态环境的改善打下了坚实的基础。 但是总的来说,只是局部有所改善,总体仍然在恶化,前景不容乐观。 目前,我国生态环境存在的主要问题是: 〈一〉 森林草原等植被遭到破坏严重,可用耕地面积减少 ,自然生态环境恶化 植被是生态环境的基础,破坏了植被也就破坏了生态环境的基础,我国的植被破坏主要表现在森林减少、草场退化等。 建国以来,我国的天然林资源不断减少
针对当前形势、企业发展的困难、希望工商联帮助协调解决的问题等方面,展开了热烈讨论。 在工商联主席的引导下,会员又对 “合作发展、共度难关 ”的理念达成共识,决定家 乡的非公经济人士们团结起来,壮大穆棱商会力量,共同发展。 针对本次座谈会中会员提出的发展困难,工商联经归纳梳理,形成 3 个针对性强的问题: 1 是企业用工难问题; 2 是传统经营模式受冲击严重问题; 3是企业发展融资难问题。
全国计算机等级证书,实用英语等级证书,中、高级制图员,中、高级维修电工,工具钳工等职业资格证书,要 求学生获得 2 种以上职业资格证 书。 机电一体化专业职业资格证书一览表 序号 职业资格证书 颁证单位 等级 1 制图员资格证书 国家劳动与社会保障部 中级或高级 2 工具钳工 国家劳动与社会保障部 中级或高级 3 维修电工 国家劳动与社会保障部 中级或高级 (三)专业建设规划与实施
0 以上规格,吊筋和膨胀螺栓的连接必须 牢固可靠,无松动。 E、主龙骨的间距按上人天花规定合理分布,一般应在 900mm 至 1200mm 之间;次龙骨间距一般为 400mm,横撑龙骨间距一般在 600mm。 F、轻钢龙骨在施工中应有起拱高度,且应不小于房间短向跨度的 /1000( 10米跨内水平线上中心提升 1CM 高) ,跨度越大,起拱随之增加。 G、所有龙骨配件必须安装牢固,不能有松动。
,先起吊单吊点侧,单吊点侧起升使梁体离开台应 3 公分,停机,观察刹车情况,对刹车做相应调整,调整好后,起落来回试验 3 次 (起升总高不能大于 10 公分 ),确保刹车正常工作。 单吊点侧调整好后,使单吊点侧离开台 座 5 公分,悬停,开始调整双吊点侧,调整方式同单吊点侧。 两侧都调整好后,可以进行同步重载试验。 2) 超负荷动载试车 起吊额定负荷的 倍重物即 495 吨作动负重载试验
措施 报批手续完备 成立相关机构 组织防汛抢险演练 8 附录二: 勘察设计单位安全生产检查表 序号 检查项目 检查标准 内容 要求与记录 A 级 ( 满足要求) B 级 ( 大部分满足要求) C 级 (基本满足要求) D 级 ( 不满足要求) 1 工程建设强制性标准 相关强制性标准要求识别完整 标准更新及时 2 工程重点部位和环节防范生产安全事故指导意见 工程重点部位明确 工程建设关键环节明确