From 00b0bdff6a396656286abbc54525241cb89291f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Wed, 21 Oct 2020 11:16:37 +0200 Subject: [PATCH] Handle range query edge case (#63397) Currently when searching with an empty string as lower bound for a range query on text-based fields we return all documents when 'gte' is used (including the lower bound) but no documents when 'gt' is used. This might seem counterintuitive since every value should be greate than the empty string. The bug has been fixed in Lucene and this PR adds a test for assuring we observe the fixed behaviour on searches now. Closes #63386 --- .../search/simple/SimpleSearchIT.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/simple/SimpleSearchIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/simple/SimpleSearchIT.java index 6a163543e3073..2ef7a961fde68 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/search/simple/SimpleSearchIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/search/simple/SimpleSearchIT.java @@ -225,6 +225,51 @@ public void testSimpleDateRange() throws Exception { assertHitCount(searchResponse, 2L); } + public void testRangeQueryKeyword() throws Exception { + createIndex("test"); + + client().admin().indices().preparePutMapping("test").setSource("field", "type=keyword").get(); + + client().prepareIndex("test").setId("0").setSource("field", "").get(); + client().prepareIndex("test").setId("1").setSource("field", "A").get(); + client().prepareIndex("test").setId("2").setSource("field", "B").get(); + client().prepareIndex("test").setId("3").setSource("field", "C").get(); + ensureGreen(); + refresh(); + + SearchResponse searchResponse = client().prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gte("A").lte("B")).get(); + assertNoFailures(searchResponse); + assertHitCount(searchResponse, 2L); + + searchResponse = client().prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gt("A").lte("B")).get(); + assertNoFailures(searchResponse); + assertHitCount(searchResponse, 1L); + + searchResponse = client().prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gte("A").lt("B")).get(); + assertNoFailures(searchResponse); + assertHitCount(searchResponse, 1L); + + searchResponse = client().prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gte(null).lt("C")).get(); + assertNoFailures(searchResponse); + assertHitCount(searchResponse, 3L); + + searchResponse = client().prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gte("B").lt(null)).get(); + assertNoFailures(searchResponse); + assertHitCount(searchResponse, 2L); + + searchResponse = client().prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gt(null).lt(null)).get(); + assertNoFailures(searchResponse); + assertHitCount(searchResponse, 4L); + + searchResponse = client().prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gte("").lt(null)).get(); + assertNoFailures(searchResponse); + assertHitCount(searchResponse, 4L); + + searchResponse = client().prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gt("").lt(null)).get(); + assertNoFailures(searchResponse); + assertHitCount(searchResponse, 3L); + } + public void testSimpleTerminateAfterCount() throws Exception { prepareCreate("test").setSettings(Settings.builder().put(SETTING_NUMBER_OF_SHARDS, 1).put(SETTING_NUMBER_OF_REPLICAS, 0)).get(); ensureGreen();