ConstantScoreRangeQuery没有为ip范围查询提供正确的结果

时间:2012-11-15 12:02:02

标签: lucene ipv6 ipv4

我正在使用ConstantScoreRangeQuery搜索范围为0.0.0.0255.255.255.255的范围内的所有IP地址。这几乎都在搜索所有IPv4地址。

我正在将所有IP地址转换为字符串并将其编入索引。例如,0.0.0.0变为00000000255.255.255.255变为ffffffff,其中每2个字符为一个八位字节。

当我搜索IP地址时,我正在创建一个查询,如下所示: ConstantScoreRangeQuery(fldIdStr, "00000000", "ffffffff", true, true)

我同时存储IPv4和IPv6。此查询也返回IPv6。

我正在使用Lucene(lucene-core-2.4.0.jar)2.4.0;

如何只获取IP范围内的IPv4地址。

2 个答案:

答案 0 :(得分:0)

  

我正在将所有IP地址转换为字符串并将其编入索引

这种做法是错误的。 ConstantScoreRangeQuery的{​​{3}}说:

  

此查询匹配查找属于的条款的文档   根据String.compareTo(String)提供的范围。它不是   对于数字范围,请改用NumericRangeQuery。

您无法使用String.compareTo(String)查询IP范围。

您需要将IP地址索引为数字,并定义逻辑,通过该逻辑定义在给定范围内(和超出)的意义。

最重要的是,ConstantScoreRangeQuery已弃用,已在版本3中删除。您确实必须升级到较新的Lucene版本(v4.0现已推出)。< / p>

答案 1 :(得分:0)

您可以使用TermRangeQuery将自定义Collator作为第六个arg传递给构造函数。

简单地实现一个Collat​​or,String.compareTo应该可以正常工作,比较你指定格式的IPv4地址,除非有一些我遗漏的东西。

要消除IPv6匹配,您可以先检查长度,根据非零长度差异返回正或负结果,如果长度相等,则只返回String.compareTo的结果。

另一个选项是,如果稍微更改索引格式是可行的,则可以使用IP版本为存储的值添加前缀,例如:v4ffffffffv6ffffffffffffffff。在这种情况下,只要您始终将该前缀应用于每个值和查询,带有您声明的参数的标准TermRangeQuery就可以很好地完成工作。