lucene 自定义合并策略_lucene/BooleanQuery倒排表合并策略.md at master · chakra-coder/lucene · GitHub...

Lucene中基本的Query类型有以下几种:

TermQuery,WildcardQuery,PhraseQuery,PrefixQuery,MultiPhraseQuery,FuzzyQuery,RegexpQuery,TermRangeQuery,NumericRangeQuery,ConstantScoreQuery,DisjunctionMaxQuery,MatchAllDocsQuery

除此以外还有一种特殊的BooleanQuery,用户可以通过该Query将查询组装成树状结构。举例如下:

+title:lucene +(+title:lucene title:luc* +title:lucene~2)

上面的查询语句表示成树的形式:

|__+ title:lucene(TermQuery)

|__+|__+ title:lucene(TermQuery)

|__ title:luc*( PrefixQuery)

|__+ title:lucene~2(FuzzyQuery)

+表示MUST,没有前缀表示SHOULD,-表示MUST_NOT,对应到BooleanQuery中,MUST表示该Term在Document中必须出现,SHOULD表示可以出现也可以不(影响打分),MUST_NOT表示必须不出现。

对于PrefixQuery,查询之前,需要将其重写成TermQuery的组合,但是当满足Prefix的Term数量大于阀值或者满足条件的倒排文档数量大于阀值时,就不会将其重写成TermQuery的组合,

此时会使用PrefixQuery构造一个QueryFilter,使用此过滤器对Term进行过滤(term.StartWith(prefix)),同理FuzzyQuery也将被重写。

在我测试的例子中,ReWrite结束之后,查询树变成:

|__+ title:lucene(TermQuery)

|__+|__+ title:lucene(TermQuery)

|__ title:luc*( PrefixQueryFilter)

|__+ | title:lucek(TermQuery)

| title:lucene(TermQuery)

| title:lucewe(TermQuery)

ReWrite从顶向下重写,可以看成是对Query树的遍历过程。

忽略打分过程,接下来就是合并倒排表了。

Lucene首先自底向上将同一父亲下的子节点归类,所有MUST的放在一起,SHOULD的放在一起,MUST_NOT的放在一起,这样做的目的是为了方便合并倒排表。

对于MUST,倒排表取交集,SHOULD取并集,MUST_NOT内部取交集,之后再和其它的取差集。

这里需要注意的是取出来的doc需要保序,对于单独的Term,其倒排表本身是有序的,因此lucene实现并集用了小顶堆,交集就是一次遍历。

MUST、SHOULD、MUST_NOT不同情况的组合会影响查询结果,(MUST|MUST_NOT)&SHOULD时SHOULD只会影响打分,其它的组合没什么好说的。

Lucene实现倒排表没有使用bitmap,为了效率,lucene使用了一些策略,具体如下:

使用FST保存词典,FST可以实现快速的Seek,这种结构在当查询可以表达成自动机时(PrefixQuery、FuzzyQuery、RegexpQuery等)效率很高。(可以理解成自动机取交集)

此种场景主要用在对Query进行rewrite的时候。

FST可以表达出Term倒排表所在的文件偏移。

倒排表使用SkipList结构。从上面的讨论可知,求倒排表的交集、并集、差集需要各种SeekTo(docId),SkipList能对Seek进行加速。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值