lucene 范围查询及其原理
2016-07-12 11:32
423 查看
适用于lucene 6.0。
Int类型的有IntPoint,Double类型的有相应的DoublePoint,以此类推。
一个被索引的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)。
prefix1:0/prefix2:01/prefix3:012/prefix4:0123
按照不同前缀长度分词,这个间隔(precision step)不一定是1,可以指定,下行这个字段就是一个默认值。
int org.apache.lucene.util.LegacyNumericUtils.PRECISION_STEP_DEFAULT = 16。
这个值越大,那么索引就越小,那么范围查询的性能(尤其是细粒度的范围查询)也越差;这个值越小,索引就越大,那么性能越差。
图2-1 字典树示例
我们要查找[423,642]这样一个range。根据图可以直观的得到,合理lucene 的query为(prefix3:423
prefix1:5 prefix2:63
prefix3:641 prefix3:642)。
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)。然后一直往上找,直到找到一个共同的祖先(肯定能找到,因为树根是所有叶子节点的祖先),对应起点,每次往上走的时候, 左边范围节点都要把它右边的兄弟节点都加进去, 右边范围节点都要把它左边的兄弟节点加进去, 若已经到达顶点, 则是将左边范围节点和右边范围节点之间的节点加进行去.相关文章推荐
- redis 安装
- 聚合函数
- 剑指offer(54)-二叉树的下一个结点
- C# 打开以对话框,获取文件夹路径 、文件的路径、文件名
- C++ #pragma 用法小结
- STL:transform
- hadoop入门第七步---hive部署安装(apache-hive-1.1.0)
- JSP页面EL表达式${param.XX}用法
- UE4角色受击动画,随机播放音效
- pycharm远程调试
- 编程的智慧
- nignx日志格式
- 用户登陆后拦截器的具体实现
- Leetcode 26. Remove Duplicates from Sorted Array (Easy) (cpp)
- Java.util.zip 压缩与解压缩工具类
- MYSQL常用内置函数详解说明
- [51nod]1289 大鱼吃小鱼
- 改良程序的11技巧
- Android属性动画实现布局的下拉展开效果
- 理解Javascript中的Function