我正在使用ConstantScoreRangeQuery
搜索范围为0.0.0.0
到255.255.255.255
的范围内的所有IP地址。这几乎都在搜索所有IPv4地址。
我正在将所有IP地址转换为字符串并将其编入索引。例如,0.0.0.0
变为00000000
,255.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地址。
答案 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传递给构造函数。
简单地实现一个Collator,String.compareTo应该可以正常工作,比较你指定格式的IPv4地址,除非有一些我遗漏的东西。
要消除IPv6匹配,您可以先检查长度,根据非零长度差异返回正或负结果,如果长度相等,则只返回String.compareTo的结果。
另一个选项是,如果稍微更改索引格式是可行的,则可以使用IP版本为存储的值添加前缀,例如:v4ffffffff
或v6ffffffffffffffff
。在这种情况下,只要您始终将该前缀应用于每个值和查询,带有您声明的参数的标准TermRangeQuery就可以很好地完成工作。