lucene 范围查询及其原理

适用于lucene 6.0。

Int类型的有IntPoint,Double类型的有相应的DoublePoint,以此类推。

1.相关类

org.apache.lucene.document.IntPoint
一个被索引的int类型的field。可以代表n维形状,可以范围搜索。
org.apache.lucene.document.IntPoint.IntPoint(String name, int... point)
构造函数。
Query org.apache.lucene.document.IntPoint.newRangeQuery(String field, int lowerValue, int upperValue)
构造一维情况下的范围查询。
Query org.apache.lucene.document.IntPoint.newRangeQuery(String field, int[] lowerValue, int[] upperValue)
构造多维情况下的范围查询。
Query org.apache.lucene.document.IntPoint.newSetQuery(String field, int... values)
构造集合查询。
Query org.apache.lucene.document.IntPoint.newExactQuery(String field, int value)

构造精确查询。内部调用的还是newRangeQuery(String field, int lowerValue, int upperValue)。

2.例子

见示例项目【https://code.csdn.net/chuchus/lucenedemo/tree/master】中 “com.yichudu.lucenedemo.query.rangequery”包下面的代码。

3.底层的算法

要想实现范围查询,需要做两部分的工作:索引期间的分词与Query的构造。

3.1 索引期间的分词

将数字转为字符串,按照不同前缀长度,切分成多个term。

3.1.1 基本思想

以int类型为例,补上前缀0,让同一个field的域值 位数都一样。假设对于“123”这个数,补上0之后为"0123",那么按照不同前缀长度分词,得到多个term。见下。
prefix1:0/prefix2:01/prefix3:012/prefix4:0123

3.1.2 实际处理

long、double等类型转字符串的细节不同。
按照不同前缀长度分词,这个间隔(precision step)不一定是1,可以指定,下行这个字段就是一个默认值。
int org.apache.lucene.util.LegacyNumericUtils.PRECISION_STEP_DEFAULT = 16。
这个值越大,那么索引就越小,那么范围查询的性能(尤其是细粒度的范围查询)也越差;这个值越小,索引就越大,那么性能越差。

3.2Query的构造

利用字典树来构造一个合理的OCCUR.OR 的booleanQuery 的clause。

3.2.1例子

在创建索引的时候可以构造出一棵字典树。假设数值转为字符串后的长度都为3,一个合理的树见图2-1.

图2-1 字典树示例

我们要查找[423,642]这样一个range。根据图可以直观的得到,合理lucene 的query为(prefix3:423
prefix1:5 prefix2:63
prefix3:641 prefix3:642)。

3.2.2构造算法

我们首先可以用shift==0找到范围的起点后终点(有可能没有相等的,比如搜索422,也会找到423)。然后一直往上找,直到找到一个共同的祖先(肯定能找到,因为树根是所有叶子节点的祖先),对应起点,每次往上走的时候, 左边范围节点都要把它右边的兄弟节点都加进去, 右边范围节点都要把它左边的兄弟节点加进去, 若已经到达顶点, 则是将左边范围节点和右边范围节点之间的节点加进行去.

时间: 2024-11-03 10:40:31

lucene 范围查询及其原理的相关文章

在jsp页面中显示lucene的查询结果,报错:org.apache.jasper.JasperException: Java heap space

问题描述 在jsp页面中显示lucene的查询结果,当返回hits的总数小于100时,可以正常显示,当结果大于100,会报如下错误:(但是在java环境下结果输出是正常的)exceptionorg.apache.jasper.JasperException:Javaheapspaceorg.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:433)org.apache.jasper.

MySQL的多表查询(笛卡尔积原理)

原文:MySQL的多表查询(笛卡尔积原理) 先确定数据要用到哪些表. 将多个表先通过笛卡尔积变成一个表. 然后去除不符合逻辑的数据(根据两个表的关系去掉). 最后当做是一个虚拟表一样来加上条件即可.   注意:列名最好使用表别名来区别.     笛卡尔积         Demo:   左,右连接,内,外连接 l             内连接: 要点:返回的是所有匹配的记录. 2.         select * from a,b where a.x = b.x               

360公布网址云查询技术原理

南都讯 记者 李宽宽 近日,在2010年最后一天被金山突指"窃取用户隐私"的360公司对外公布了360网盾网址云查询技术原理,并表示公司与金山同样采用的都是"恶意网址上传机制",360技术副总裁谭晓生解释称,这是行业通行做法:"安全软件在发现用户浏览器受到恶意代码攻击时,会将可疑恶意网址上传到服务器进行自动分析,然后把鉴定出来的挂马网址加入恶意网址库,除了金山和360外,诺顿.趋势等也都有类似的机制,"安全软件在上传时,如果用户同时打开了多个网页

WebGIS中兴趣点简单查询、基于Lucene分词查询的设计和实现

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 兴趣点查询是指:输入框中输入地名.人名等查询信息后,地图上可以展示出对应信息所在的地址,并且根据需求以不同方式展示出相关地址的属性信息等. 以百度地图为例:                         2.原理 所谓兴趣点查询,也就是前台输入描述信息后,后台根据该描述信息在地理数据库中查询到符合查询信息的地理数据和与此对应的属性数据,然后将数据返回给前台

Lucene.net查询不准确可能是什么原因

问题描述 我用盘古分词+Lucene.net做了一个全文检索的功能,但是有一个bug,比如输入"质量-安全",结果应该是只含"质量"关键字不含"安全"关键字,但是实际查询出来的,有个别结果(大部分结果符合要求)既有"质量"关键字,也有"安全"关键字.有哪位熟悉Lucene.net的老师指导一下,出现这个bug可能的原因是什么?可能是建索引那里的问题吗?还是分词有问题? 解决方案 解决方案二:上代码创建索引p

用的lucene 为什么查询的结果重复呢

问题描述 用的lucene 索引建立没有重复 为什么查询的结果重复呢代码如下:IndexSearcher searchers = new IndexSearcher(LuceneManager.article_index_path);Analyzer analyzer = new LuceneManager().getAnalyzer();QueryParser queryParser = new QueryParser("title", analyzer);Query query =

360网盾网址云查询技术原理说明

2010年12月31日,金山公司召开新闻发布会,指责360"收集3亿用户密码等隐私"."上传内网文件地址"."追踪用户上网行为"等,并通过弹窗发布所谓"一级安全预警",宣称"上亿用户密码遭泄漏",并公开建议用户卸载360. 金山公布的所谓"360收集用户隐私",实为360网盾上传的不在360恶意网址库中的未知挂马网被木马毒病攻击的网址样本.金山公司在内的国内外安全软件厂商都采用的是相同的

(十九)WebGIS中I查询的原理及设计(包含AGS、GeoServer、Supermap)

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 我们在使用arcmap时,经常会用到被称为I查询的工具.具体功能便是,当激活I查询功能后,鼠标点击到某个要素上时,界面上会弹出一个对话框用来显示该要素的各属性信息.该功能截图如下:                         2.原理 在WebGIS中设计和实现该功能之前,我们有必要对该功能的原理做一个了解. 在OGC的WMS标准中规定了一个接口:Get

从一条select语句看Oracle数据库查询工作原理

假如,我们现在利用Select语句从数据库查询数据,Oracle数据库是如何运作的呢?从中我们可以领悟到什么呢?下面,就结合一条简单的select语句,看看Oracle数据库后台的运作机制.这对于我们之后的系统管理与故障排除非常有帮助. 第一步:客户端把语句发给服务器端执行. 当我们在客户端执行select语句时,客户端会把这条SQL语句发送给服务器端,让服务器端的进程来处理这语句.也就是说,Oracle客户端是不会做任何的操作,他的主要任务就是把客户端产生的一些SQL语句发送给服务器端.虽然在