diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e2c1ee1a7677..ae2384b176fd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Use Bad Request status for InputCoercionException ([#18161](https://github.com/opensearch-project/OpenSearch/pull/18161)) - Null check field names in QueryStringQueryBuilder ([#18194](https://github.com/opensearch-project/OpenSearch/pull/18194)) - Avoid NPE if on SnapshotInfo if 'shallow' boolean not present ([#18187](https://github.com/opensearch-project/OpenSearch/issues/18187)) +- Fix regex query from query string query to work with field alias ([#18215](https://github.com/opensearch-project/OpenSearch/issues/18215)) ### Security diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search/61_query_string_field_alias.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search/61_query_string_field_alias.yml new file mode 100644 index 0000000000000..c99d94d7457e3 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search/61_query_string_field_alias.yml @@ -0,0 +1,56 @@ +setup: + - skip: + version: " - 3.0.99" + reason: "regex query over field alias support starts 3.1" + + - do: + indices.create: + index: test_index + body: + settings: + number_of_shards: 1 + number_of_replicas: 0 + mappings: + properties: + test: + type: text + test_alias: + type: alias + path: test + + - do: + bulk: + refresh: true + body: | + {"index":{"_index":"test_index","_id":"1"}} + {"test":"hello"} + {"index":{"_index":"test_index","_id":"2"}} + {"test":"world"} + +--- +"regex search on normal field": + - do: + search: + rest_total_hits_as_int: true + index: test_index + body: + query: + query_string: + query: "test: /h[a-z].*/" + + - match: {hits.total: 1} + - match: {hits.hits.0._id: "1"} + +--- +"regex search on alias field": + - do: + search: + rest_total_hits_as_int: true + index: test_index + body: + query: + query_string: + query: "test_alias: /h[a-z].*/" + + - match: {hits.total: 1} + - match: {hits.hits.0._id: "1"} diff --git a/server/src/main/java/org/opensearch/index/search/QueryStringQueryParser.java b/server/src/main/java/org/opensearch/index/search/QueryStringQueryParser.java index e67d9c7e08908..7bfb3475d6744 100644 --- a/server/src/main/java/org/opensearch/index/search/QueryStringQueryParser.java +++ b/server/src/main/java/org/opensearch/index/search/QueryStringQueryParser.java @@ -56,6 +56,7 @@ import org.apache.lucene.search.SynonymQuery; import org.apache.lucene.search.WildcardQuery; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.automaton.RegExp; import org.opensearch.common.lucene.search.Queries; import org.opensearch.common.regex.Regex; import org.opensearch.common.unit.Fuzziness; @@ -787,8 +788,12 @@ private Query getRegexpQuerySingle(String field, String termStr) throws ParseExc if (currentFieldType == null) { return newUnmappedFieldQuery(field); } - setAnalyzer(getSearchAnalyzer(currentFieldType)); - return super.getRegexpQuery(field, termStr); + if (forceAnalyzer != null) { + setAnalyzer(forceAnalyzer); + } + // query string query normalizes search value + termStr = getAnalyzer().normalize(currentFieldType.name(), termStr).utf8ToString(); + return currentFieldType.regexpQuery(termStr, RegExp.ALL, 0, getDeterminizeWorkLimit(), getMultiTermRewriteMethod(), context); } catch (RuntimeException e) { if (lenient) { return newLenientFieldQuery(field, e);