Lucene BooleanQuery相关算法
BooleanQuery对两种不同查询场景执行不同的算法:
场景1:
所有的子句都必须满足,而且所有的子句里没有嵌套BooleanQuery。
例:
a AND b AND c
上面语句表示要同时包含a,b,c三个字符(词元)的文档,假如现在索引里包含a的文档有4,6,8;b的文档有:2,4,6;c的文档有:3,4,5,这个语句就是找出编号为4的这个文档。
注:在倒排索引里存储的包含某个词元的文档列表都是从小到大排列的。
初始状态如下:
a | b | c |
-> 4 | -> 2 | -> 3 |
6 | 4 | 4 |
8 | 6 | 5 |
指针表示当前遍历到哪个文档
第一步:按照每个词元文档列表的第一个文档对词元排序。排序以后的状态如下:
b | c | a |
-> 2 | -> 3 | -> 4 |
4 | 4 | 6 |
6 | 5 | 8 |
第二步:判断第一个词元(b)的当前遍历文档(2)是否小于最后一个词元(a)的当前遍历文档(4)。如果小于,则表示第一个词元的当前遍历文档不是符合的文档,如果是符合的最后一个词元的当前文档应该和第一个词元的相同。
第三步: 第一个词元文档位置(2)跳转到最后一个词元的当前遍历的文档(4),跳转以后的状态如下:
b | c | a |
2 | -> 3 | -> 4 |
-> 4 | 4 | 6 |
6 | 5 | 8 |
第四步: 将第一个词元放到词元列表最后,重置位置后状态如下:
c | a | b |
-> 3 | -> 4 | 2 |
4 | 6 | -> 4 |
5 | 8 | 6 |
重复第二、三、四步,直到找到第一个词元的当前遍历文档ID和最后一个词元的相同,则这个文档就是符合查询要求的文档。
这种场景的代码实现在ConjunctionScorer类里,主要的代码逻辑在方法doNext里:
while (more && first().doc() < last().doc()) { // find doc w/ all clauses
more = first().skipTo(last().doc()); // skip first upto last
scorers.addLast(scorers.removeFirst()); // move first to last
}
这里会不断的判断第一个词元的当前文档是否小于最后一个词元的当前文档,如果不相同,则第一个词元的文档跳转到最后一个词元的文档位置。
排序是在第一次进去的时候在init方法里做的。
场景2:
除了上面第一种场景就是第二种场景,第一种场景因为排序的原因,不需要遍历所有的文档,第二种场景需要遍历所有的文档。
第二种场景的实现在BooleanScorer类里,
每次往BooleanScorer类里添加一个子句,会记录当前这个子句的序号和这个子句的定义,是必须满足还是必须不满足。这个数据记录在requiredMask和prohibitedMask中,这两个数是int类型,里面每一位都代表一个子句。requiredMask记录了哪些子句必须满足;prohibitedMask记录了哪些子句必须不能满足。比如一共有5个子句,1、3、5必须满足,2、4必须不能满足,则requiredMask二进制的值为: 10101。prohibitedMask的值为: 01010。
当调用next的时候会批量从各子句中取出符合这些子句的部分文档(文档ID批范围,1024为一批)到内存中的一个缓存BucketTabke里,在这个缓存里会根据文档ID进行聚合(Bucket),每个文档ID都有个满足哪些子句的属性bits。
然后遍历这些文档,那些bits里包含所有必须符合子句且不包含所有必须排查子句的文档是最终符合的文档。这个判断是通过bits和上面requiredMask和prohibitedMask做位运算实现的。
if ((current.bits & prohibitedMask) == 0 &&
(current.bits & requiredMask) == requiredMask) {
return true;
}
Lucene BooleanQuery相关算法的更多相关文章
- 二叉树-你必须要懂!(二叉树相关算法实现-iOS)
这几天详细了解了下二叉树的相关算法,原因是看了唐boy的一篇博客(你会翻转二叉树吗?),还有一篇关于百度的校园招聘面试经历,深刻体会到二叉树的重要性.于是乎,从网上收集并整理了一些关于二叉树的资料,及 ...
- 数据结构(C语言版)顺序栈相关算法的代码实现
这两天完成了栈的顺序存储结构的相关算法,包括初始化.压栈.出栈.取栈顶元素.判断栈是否为空.返回栈长度.栈的遍历.清栈.销毁栈.这次的实现过程有两点收获,总结如下: 一.清楚遍历栈的概念 栈的遍历指的 ...
- [联赛可能考到]图论相关算法——COGS——联赛试题预测
COGS图论相关算法 最小生成树 Kruskal+ufs int ufs(int x) { return f[x] == x ? x : f[x] = ufs(f[x]); } int Kruskal ...
- [java,2017-05-15] 内存回收 (流程、时间、对象、相关算法)
内存回收的流程 java的垃圾回收分为三个区域新生代.老年代. 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间:如果有 不进行垃圾回收 ,对象直接在伊甸园存储:如果伊甸园内存已满,会进行一次m ...
- 【STL学习】堆相关算法详解与C++编程实现(Heap)
转自:https://blog.csdn.net/xiajun07061225/article/details/8553808 堆简介 堆并不是STL的组件,但是经常充当着底层实现结构.比如优先级 ...
- TCP系列39—拥塞控制—2、拥塞相关算法及基础知识
一.拥塞控制的相关算法 早期的TCP协议只有基于窗口的流控(flow control)机制而没有拥塞控制机制,因而易导致网络拥塞.1988年Jacobson针对TCP在网络拥塞控制方面的不足,提出了& ...
- UCI机器学习库和一些相关算法(转载)
UCI机器学习库和一些相关算法 各种机器学习任务的顶级结果(论文)汇总 https://github.com//RedditSota/state-of-the-art-result-for-machi ...
- Lucene BooleanQuery中的Occur.MUST与Occur.Should
https://www.cnblogs.com/weipeng/archive/2012/04/18/2455079.html 1. 多个MUST的组合不必多说,就是交集 2. MUST和SH ...
- 采样方法(二)MCMC相关算法介绍及代码实现
采样方法(二)MCMC相关算法介绍及代码实现 2017-12-30 15:32:14 Dark_Scope 阅读数 10509更多 分类专栏: 机器学习 版权声明:本文为博主原创文章,遵循CC 4 ...
随机推荐
- gzip格式分析与识别
" 介绍gzip格式,识别gzip压缩的数据流量." 在协议分析过程中,经常会发现gzip压缩的数据,例如在HTTP协议中,在HTTP头中会标示,内容编码为gzip.DEFLATE ...
- ABP进阶教程2 - 组合查询
点这里进入ABP进阶教程目录 更新数据传输对象 打开应用层(即JD.CRS.Application)的Course\Dto\GetAllCoursesInput.cs //Course数据传输对象(查 ...
- gitlab从开发分支合并代码到master分支
你敢相信这是个码农? 新项目开发完成,代码要封版.开发分支是dev,将代码合并到master时可费了劲儿了,上周我们几个同事前前后后折腾了两天,还是有问题. 今天上完线必须要封版了.所以务必得搞定. ...
- PHP多进程系列笔(转)
本系列文章将向大家讲解pcntl_*系列函数,从而更深入的理解进程相关知识. PCNTL在PHP中进程控制支持默认是关闭的.您需要使用 --enable-pcntl 配置选项重新编译PHP的 CGI或 ...
- [Go] gocron源码阅读-groutine与channel应用到信号捕获
直接使用go 函数名()可以开启一个grountine,channel可以接收信息并且如果没有数据时会阻塞住channel对应的是底层数据结构的引用,复制channel和函数传参都是拷贝的引用make ...
- 使用Apache服务部署静态网站2019-7-5
使用Apache服务部署静态网站 第1步:把镜像挂载到系统中 第2步:使用vim文件编辑器创建YUM仓库的配置文件 [root@study ~]# vim /etc/yum.repos.d/abc.r ...
- MD文件图片base64自动编码
看工具链接请直接将文章拉到最后.. 概述 不知道你在使用markdown写文章的时候有没有遇到过这样的烦恼, 文件写完了, 想将写完的文章粘贴到博客的时候, 你满心欢喜的复制粘贴, 但是发现图片根本复 ...
- day59_9_25中间键与登录认证
一.django中间件简介. 在django中,有这样的生命周期: 中间件就是处于wsgiref和urls模块中间,可以拦截所有的请求,其中有7个默认中间件: MIDDLEWARE = [ 'djan ...
- 20191004 「HZOJ NOIP2019 Round #9」20191004模拟
综述 第一次 rk1 ,激动. 题目是 COCI 18/19 Round #1 的三至五题. 得分 \(100+100+20\) \(\mathrm{cipele}\) 问题描述 HZOJ1313 题 ...
- C语言前置知识汇编基础--总线【地址总线,控制总线,数据总线】练习题
寻址就是用一个数字表示一个字节存储单元的地址,而不是表示这个存储单元中的内容,所以不用乘以8. 1. 1个CPU的寻址能力为8KB,那么它的地址总线宽度是多少? 8*1024=8192 共有8 ...