Repository: blevesearch/bleve
Pull request #1735 (2022-10-05 18:09:51)

MB-40604: Support IPRange query
Related: https://github.com/blevesearch/bleve/pull/1546


Patch:
diff --git a/go.mod b/go.mod
index d5a42365..0c6d7674 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
 	github.com/RoaringBitmap/roaring v0.9.4
 	github.com/bits-and-blooms/bitset v1.2.0
 	github.com/blevesearch/bleve_index_api v1.0.3
-	github.com/blevesearch/geo v0.1.14
+	github.com/blevesearch/geo v0.1.15
 	github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475
 	github.com/blevesearch/go-porterstemmer v1.0.3
 	github.com/blevesearch/goleveldb v1.0.1
diff --git a/go.sum b/go.sum
index de7139ae..29014657 100644
--- a/go.sum
+++ b/go.sum
@@ -6,8 +6,8 @@ github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjL
 github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
 github.com/blevesearch/bleve_index_api v1.0.3 h1:DDSWaPXOZZJ2BB73ZTWjKxydAugjwywcqU+91AAqcAg=
 github.com/blevesearch/bleve_index_api v1.0.3/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
-github.com/blevesearch/geo v0.1.14 h1:TTDpJN6l9ck/cUYbXSn4aCElNls0Whe44rcQKsB7EfU=
-github.com/blevesearch/geo v0.1.14/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
+github.com/blevesearch/geo v0.1.15 h1:0NybEduqE5fduFRYiUKF0uqybAIFKXYjkBdXKYn7oA4=
+github.com/blevesearch/geo v0.1.15/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
 github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:kDy+zgJFJJoJYBvdfBSiZYBbdsUL0XcjHYWezpQBGPA=
 github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
 github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
diff --git a/search/query/query.go b/search/query/query.go
index 60add3b6..ee876c8e 100644
--- a/search/query/query.go
+++ b/search/query/query.go
@@ -292,6 +292,17 @@ func ParseQuery(input []byte) (Query, error) {
 		}
 		return &rv, nil
 	}
+
+	_, hasCIDR := tmp["cidr"]
+	if hasCIDR {
+		var rv IPRangeQuery
+		err := json.Unmarshal(input, &rv)
+		if err != nil {
+			return nil, err
+		}
+		return &rv, nil
+	}
+
 	return nil, fmt.Errorf("unknown query type")
 }
 


Test patch:
diff --git a/search/query/query_test.go b/search/query/query_test.go
index 1794f16d..0082e8ac 100644
--- a/search/query/query_test.go
+++ b/search/query/query_test.go
@@ -205,6 +205,14 @@ func TestParseQuery(t *testing.T) {
 			input:  []byte(`{"bool": true}`),
 			output: NewBoolFieldQuery(true),
 		},
+		{
+			input: []byte(`{"field": "x", "cidr": "1.2.3.0/4"}`),
+			output: func() Query {
+				q := NewIPRangeQuery("1.2.3.0/4")
+				q.SetField("x")
+				return q
+			}(),
+		},
 		{
 			input:  []byte(`{"madeitup":"queryhere"}`),
 			output: nil,
diff --git a/search_test.go b/search_test.go
index ee8846a0..61cbe289 100644
--- a/search_test.go
+++ b/search_test.go
@@ -1889,3 +1889,47 @@ func TestHightlightingWithHTMLCharacterFilter(t *testing.T) {
 			gotFragment, expectedFragment)
 	}
 }
+
+func TestIPRangeQuery(t *testing.T) {
+	idxMapping := NewIndexMapping()
+	im := NewIPFieldMapping()
+	dmap := mapping.NewDocumentMapping()
+	dmap.AddFieldMappingsAt("ip_content", im)
+	idxMapping.DefaultMapping = dmap
+
+	tmpIndexPath := createTmpIndexPath(t)
+	defer cleanupTmpIndexPath(t, tmpIndexPath)
+
+	idx, err := New(tmpIndexPath, idxMapping)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func() {
+		err = idx.Close()
+		if err != nil {
+			t.Fatal(err)
+		}
+	}()
+
+	ipContent := "192.168.10.11"
+	if err = idx.Index("doc", map[string]string{
+		"ip_content": ipContent,
+	}); err != nil {
+		t.Fatal(err)
+	}
+
+	q := query.NewIPRangeQuery("192.168.10.0/24")
+	q.SetField("ip_content")
+	sr := NewSearchRequest(q)
+
+	searchResults, err := idx.Search(sr)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(searchResults.Hits) != 1 ||
+		searchResults.Hits[0].ID != "doc" {
+		t.Fatal("Expected the 1 result - doc")
+	}
+}