【问题标题】:ConstantScoreRangeQuery is not giving correct results for ip range queriesConstantScoreRangeQuery 没有为 ip 范围查询提供正确的结果
【发布时间】:2012-11-15 12:02:01
【问题描述】:

我正在使用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 地址。

【问题讨论】:

    标签: lucene ipv6 ipv4


    【解决方案1】:

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

    这种方法是错误的。 ConstantScoreRangeQueryJavadoc 说:

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

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

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

    最重要的是,ConstantScoreRangeQuery 已被弃用,并已在版本 3 中删除。您真的必须升级到更新的 Lucene 版本(v4.0 现已推出)。

    【讨论】:

    • 我的回答中可能遗漏了一些东西。为什么不能将 IPv4 地址与 String.compareTo 进行比较?在我看来,字典顺序应该可以很好地比较两个保证相等长度的十六进制数。
    • 您将如何比较 ipv4 地址和 ipv6 地址?另外,不要忘记有 CIDR 表示法和整数表示法,例如http://2915189354(删除空格以使链接正常工作)
    • 是的,在没有指定符号的情况下比较 IP 地址非常复杂,但鉴于 OP 通过保证格式(只需 8 个十六进制数字)消除了 CIDR、整数甚至点十进制符号,唯一的问题是消除 IPv6 结果,对吧?
    • 好的,谢谢。想确定我在这方面的想法。
    【解决方案2】:

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

    只需实现一个 Collat​​or,String.compareTo 应该可以很好地比较您指定格式的 IPv4 地址,除非我缺少某些东西。

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

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

    【讨论】:

      猜你喜欢
      • 2018-04-11
      • 2021-04-28
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 2013-08-25
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多