From 2ad3608245080952edb7f2643e6d20054046e928 Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Tue, 5 Sep 2017 15:10:05 +0200 Subject: [PATCH] percolator: handle point queries with 2 or more dimensions correctly --- .../percolator/QueryAnalyzer.java | 4 ++ .../percolator/PercolatorQuerySearchIT.java | 41 +++++++++++++++++++ .../percolator/QueryAnalyzerTests.java | 10 +++++ 3 files changed, 55 insertions(+) diff --git a/modules/percolator/src/main/java/org/elasticsearch/percolator/QueryAnalyzer.java b/modules/percolator/src/main/java/org/elasticsearch/percolator/QueryAnalyzer.java index 77f937e680c..e398886a45e 100644 --- a/modules/percolator/src/main/java/org/elasticsearch/percolator/QueryAnalyzer.java +++ b/modules/percolator/src/main/java/org/elasticsearch/percolator/QueryAnalyzer.java @@ -355,6 +355,10 @@ final class QueryAnalyzer { private static BiFunction, Result> pointRangeQuery() { return (query, boosts) -> { PointRangeQuery pointRangeQuery = (PointRangeQuery) query; + if (pointRangeQuery.getNumDims() != 1) { + throw new UnsupportedQueryException(query); + } + byte[] lowerPoint = pointRangeQuery.getLowerPoint(); byte[] upperPoint = pointRangeQuery.getUpperPoint(); byte[] interval = new byte[16]; diff --git a/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorQuerySearchIT.java b/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorQuerySearchIT.java index 17833864a42..53ebe74078b 100644 --- a/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorQuerySearchIT.java +++ b/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorQuerySearchIT.java @@ -23,6 +23,8 @@ import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; @@ -35,11 +37,16 @@ import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.test.ESIntegTestCase; +import java.util.Arrays; + import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.yamlBuilder; import static org.elasticsearch.index.query.QueryBuilders.boolQuery; import static org.elasticsearch.index.query.QueryBuilders.commonTermsQuery; +import static org.elasticsearch.index.query.QueryBuilders.geoBoundingBoxQuery; +import static org.elasticsearch.index.query.QueryBuilders.geoDistanceQuery; +import static org.elasticsearch.index.query.QueryBuilders.geoPolygonQuery; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery; @@ -216,6 +223,40 @@ public class PercolatorQuerySearchIT extends ESIntegTestCase { assertThat(response.getHits().getAt(0).getId(), equalTo("10")); } + public void testPercolatorGeoQueries() throws Exception { + assertAcked(client().admin().indices().prepareCreate("test") + .addMapping("type", "field1", "type=geo_point", "field2", "type=geo_shape", "query", "type=percolator") + ); + + client().prepareIndex("test", "type", "1") + .setSource(jsonBuilder().startObject().field("query", + geoDistanceQuery("field1").point(52.18, 4.38).distance(50, DistanceUnit.KILOMETERS)) + .endObject()).get(); + + client().prepareIndex("test", "type", "2") + .setSource(jsonBuilder().startObject().field("query", + geoBoundingBoxQuery("field1").setCorners(52.3, 4.4, 52.1, 4.6)) + .endObject()).get(); + + client().prepareIndex("test", "type", "3") + .setSource(jsonBuilder().startObject().field("query", + geoPolygonQuery("field1", Arrays.asList(new GeoPoint(52.1, 4.4), new GeoPoint(52.3, 4.5), new GeoPoint(52.1, 4.6)))) + .endObject()).get(); + refresh(); + + BytesReference source = jsonBuilder().startObject() + .startObject("field1").field("lat", 52.20).field("lon", 4.51).endObject() + .endObject().bytes(); + SearchResponse response = client().prepareSearch() + .setQuery(new PercolateQueryBuilder("query", source, XContentType.JSON)) + .addSort("_id", SortOrder.ASC) + .get(); + assertHitCount(response, 3); + assertThat(response.getHits().getAt(0).getId(), equalTo("1")); + assertThat(response.getHits().getAt(1).getId(), equalTo("2")); + assertThat(response.getHits().getAt(2).getId(), equalTo("3")); + } + public void testPercolatorQueryExistingDocument() throws Exception { assertAcked(client().admin().indices().prepareCreate("test") .addMapping("type", "field1", "type=keyword", "field2", "type=keyword", "query", "type=percolator") diff --git a/modules/percolator/src/test/java/org/elasticsearch/percolator/QueryAnalyzerTests.java b/modules/percolator/src/test/java/org/elasticsearch/percolator/QueryAnalyzerTests.java index e1e28b2bbee..81856a1d213 100644 --- a/modules/percolator/src/test/java/org/elasticsearch/percolator/QueryAnalyzerTests.java +++ b/modules/percolator/src/test/java/org/elasticsearch/percolator/QueryAnalyzerTests.java @@ -23,6 +23,7 @@ import org.apache.lucene.document.FloatPoint; import org.apache.lucene.document.HalfFloatPoint; import org.apache.lucene.document.InetAddressPoint; import org.apache.lucene.document.IntPoint; +import org.apache.lucene.document.LatLonPoint; import org.apache.lucene.document.LongPoint; import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.index.Term; @@ -743,6 +744,15 @@ public class QueryAnalyzerTests extends ESTestCase { assertArrayEquals(ranges.get(0).range.upperPoint, InetAddressPoint.encode(InetAddresses.forString("192.168.1.255"))); } + public void testTooManyPointDimensions() { + // For now no extraction support for geo queries: + Query query1 = LatLonPoint.newBoxQuery("_field", 0, 1, 0, 1); + expectThrows(UnsupportedQueryException.class, () -> analyze(query1, Collections.emptyMap())); + + Query query2 = LongPoint.newRangeQuery("_field", new long[]{0, 0, 0}, new long[]{1, 1, 1}); + expectThrows(UnsupportedQueryException.class, () -> analyze(query2, Collections.emptyMap())); + } + public void testIndexOrDocValuesQuery() { Query query = new IndexOrDocValuesQuery(IntPoint.newRangeQuery("_field", 10, 20), SortedNumericDocValuesField.newSlowRangeQuery("_field", 10, 20));