[ lucene FAQ ] NumericField的NumericRangeQuery和QueryParser失效问题

我们在对数值型字段进行检索时(范围检索、排序等),如果使用传统的文本类型将发生错误!因为文本和数值的比较方式不一样,一个是数值大小,一个是文本先后顺序,这个很容易理解。

可参见:lucene问题_检索结果怎么排序?对于不同类型(例如int型)的字段排序有什么区别吗?

 

当我们索引中有个别字段采用NumericField时,排序没有什么问题。

例如:

//索引
doc.add(new NumericField("f", Store.YES, true).setIntValue(f));
...
//检索,排序
Sort sort = new Sort(new SortField("f", SortField.INT));

这时,我们想做范围检索,问题就出现了!

//检索1-20内的数据
Query q1 = parser.parse("f:[1 TO 20]");

这种方式检索不到数据,但是换下面这种方式就好了!

//使用NumericRangeQuery
Query q = NumericRangeQuery.newIntRange("f", 1, 20, true, true);

为什么会出现这种问题?

比较粗略的说,就是QueryParser并不清楚哪个字段是数值型的,而它统一采用的是String型的比较方式(和字典中的term采用文本比较)。而且数字型字段的term底层存储也不一样,这里没具体研究!

 

现在存在这样一个问题:如果统一使用QueryParser进行语法解析,那么针对数值型字段的范围检索需要单独处理,十分不方便,怎么处理?

有两种方式:

方式1:

对QueryParser进行扩展,对数值型字段的范围检索,采用NumericRangeQuery。

 

方式2:

不用数值型字段,就采用传统的字符串,那么怎么保障排序和范围检索不出错呢?

我们可以首先对数值型字段转成字符串,然后补全N位,不做N位,左补0。

例如:数值型11,5,41,按照数值排序(升序)就是:5,11,41;

如果直接转成字符串:"11","5","41",按照字符串排序(升序)就是:"11","41","5";这显然就错了。

那么如果对字符串进行“补码”(不是二级制的补码),统一补全3位(补全多少位视数值范围而定),那么就转换成:"011","005","041",

按照字符串排序(升序)就是:"005","011","041",这就解决了排序问题。范围检索类似处理。

具体参见:http://wiki.apache.org/lucene-java/SearchNumericalFields

 


尚未解决的疑惑:

1.数值型底层存储结构。

2.排序的具体实现方式。

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值