diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search/270_wildcard_fieldtype_queries.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search/270_wildcard_fieldtype_queries.yml index cd7ac1450563f..4415aa19edb2f 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/search/270_wildcard_fieldtype_queries.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search/270_wildcard_fieldtype_queries.yml @@ -50,6 +50,10 @@ setup: id: 5 body: my_field: "AbCd" + - do: + index: + index: test + id: 6 - do: indices.refresh: {} @@ -198,3 +202,26 @@ setup: my_field: value: ".*06-08.*Cluster-Manager Node.*" - match: { hits.total.value: 0 } + +--- +"wildcard match-all works": + - do: + search: + index: test + body: + query: + wildcard: + my_field: + value: "*" + - match: { hits.total.value: 5 } +--- +"regexp match-all works": + - do: + search: + index: test + body: + query: + wildcard: + my_field: + value: ".*" + - match: { hits.total.value: 5 } diff --git a/server/src/main/java/org/opensearch/index/mapper/WildcardFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/WildcardFieldMapper.java index 3739a07e425bd..15f1a1b15abd1 100644 --- a/server/src/main/java/org/opensearch/index/mapper/WildcardFieldMapper.java +++ b/server/src/main/java/org/opensearch/index/mapper/WildcardFieldMapper.java @@ -448,14 +448,14 @@ public Query wildcardQuery(String value, MultiTermQuery.RewriteMethod method, bo }; } - return new WildcardMatchingQuery( - name(), - matchAllTermsQuery(name(), getRequiredNGrams(finalValue)), - matchPredicate, - value, - context, - this - ); + Set requiredNGrams = getRequiredNGrams(finalValue); + Query approximation; + if (requiredNGrams.isEmpty()) { + approximation = this.existsQuery(context); + } else { + approximation = matchAllTermsQuery(name(), requiredNGrams); + } + return new WildcardMatchingQuery(name(), approximation, matchPredicate, value, context, this); } // Package-private for testing @@ -540,7 +540,11 @@ public Query regexpQuery( Automaton automaton = regExp.toAutomaton(maxDeterminizedStates); CompiledAutomaton compiledAutomaton = new CompiledAutomaton(automaton); - return new WildcardMatchingQuery(name(), regexpToQuery(name(), regExp), s -> { + Query approximation = regexpToQuery(name(), regExp); + if (approximation instanceof MatchAllDocsQuery) { + approximation = existsQuery(context); + } + return new WildcardMatchingQuery(name(), approximation, s -> { BytesRef valueBytes = BytesRefs.toBytesRef(s); return compiledAutomaton.runAutomaton.run(valueBytes.bytes, valueBytes.offset, valueBytes.length); }, "/" + value + "/", context, this); @@ -704,7 +708,7 @@ private WildcardMatchingQuery( @Override public String toString(String s) { - return "WildcardMatchingQuery(" + fieldName + "\"" + patternString + "\")"; + return "WildcardMatchingQuery(" + fieldName + ":\"" + patternString + "\")"; } @Override diff --git a/server/src/test/java/org/opensearch/index/mapper/WildcardFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/WildcardFieldTypeTests.java index f03364054c166..ac76c79132844 100644 --- a/server/src/test/java/org/opensearch/index/mapper/WildcardFieldTypeTests.java +++ b/server/src/test/java/org/opensearch/index/mapper/WildcardFieldTypeTests.java @@ -149,4 +149,18 @@ public void testRegexpQuery() { assertTrue(actualMatchingQuery.getSecondPhaseMatcher().test("abcdjk")); assertTrue(actualMatchingQuery.getSecondPhaseMatcher().test("abefqwertyhi")); } + + public void testWildcardMatchAll() { + String pattern = "*"; + MappedFieldType ft = new WildcardFieldMapper.WildcardFieldType("field"); + Query actual = ft.wildcardQuery(pattern, null, null); + assertEquals(new WildcardFieldMapper.WildcardMatchingQuery("field", ft.existsQuery(null), "*"), actual); + } + + public void testRegexpMatchAll() { + String pattern = ".*"; + MappedFieldType ft = new WildcardFieldMapper.WildcardFieldType("field"); + Query actual = ft.regexpQuery(pattern, 0, 0, 1000, null, null); + assertEquals(new WildcardFieldMapper.WildcardMatchingQuery("field", ft.existsQuery(null), "/.*/"), actual); + } }