2012-11-15 71 views
1

我正在使用ConstantScoreRangeQuery來搜索範圍爲0.0.0.0255.255.255.255範圍內的所有IP地址。這幾乎是搜索所有IPv4地址。ConstantScoreRangeQuery未給出ip範圍查詢的正確結果

我將我所有的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地址?

回答

0

我將我所有的IP地址字符串和索引他們

這種做法是錯誤的。的ConstantScoreRangeQueryJavadoc說:

此查詢的文件相匹配尋找落入根據String.compareTo(string)的 提供的範圍方面。它不是用於數值範圍的 ,而是使用NumericRangeQuery。

您無法通過String.compareTo(String)查詢IP範圍。

您需要將IP地址作爲數字進行索引,並定義用於定義在給定範圍內(和超出)的含義的邏輯。

最重要的是,ConstantScoreRangeQuery已棄用,且已在版本3中刪除。您真的需要才能升級到更新的Lucene版本(v4.0已發佈)。

+0

我可能在我的答案中缺少某些東西。爲什麼不能將IPv4地址與String.compareTo進行比較?在我看來,字典順序應該可以很好地用於比較兩個保證等長的十六進制數。 – femtoRgon

+0

如何比較ipv4地址和ipv6地址?另外,不要忘記有CIDR表示法和整數表示法,例如http:// 2915189354(刪除空格以獲取鏈接的工作) – mindas

+0

是的,比較IP地址時沒有指定的記號是非常複雜的,但是考慮到OP通過保證消除了CIDR,整數,甚至點十進制記號一個格式(簡單的8位十六進制數字),唯一的問題就是消除IPv6結果,對嗎? – femtoRgon

0

您可以使用TermRangeQuery自定義Collator作爲第六個參數傳遞給構造函數。

只需實現一個Collat​​or,String.compareTo應該可以正常工作,以便按照您指定的格式對IPv4地址進行比較,除非有某些我錯過了。

要消除IPv6匹配,您可以首先檢查長度,根據非零長度差異返回正值或負值結果,如果長度相等,則返回String.compareTo的結果。

另一種選擇是,如果可以稍微更改索引格式,則可以使用IP版本前綴存儲的值,例如:v4ffffffffv6ffffffffffffffff。在這種情況下,只要您始終將該前綴應用於每個值和查詢,那麼使用您聲明的參數的標準TermRangeQuery應該很好地完成這項工作。

相關問題