From 6617c87e1bd4517215b143c84137eb77b6597c66 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Mon, 29 Jul 2024 15:19:29 -0700 Subject: [PATCH 01/23] Adding new rewrite override parameter to terms query Signed-off-by: Harsha Vamsi Kalluri --- CHANGELOG.md | 1 + .../index/mapper/KeywordFieldMapper.java | 60 +++++++++++++------ .../index/mapper/MappedFieldType.java | 8 +++ .../index/mapper/RewriteOverride.java | 29 +++++++++ .../index/query/TermsQueryBuilder.java | 45 ++++++++++++-- .../index/query/support/QueryParsers.java | 26 ++++++++ 6 files changed, 146 insertions(+), 23 deletions(-) create mode 100644 server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cc918b2ac089..a4fee25885e39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Bump `actions/github-script` from 6 to 7 ([#14997](https://github.com/opensearch-project/OpenSearch/pull/14997)) ### Changed +- Updated `termsQuery` in `KeywordField` to set custom rewrite_override before executing query ### Deprecated diff --git a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java index 2116ac522b705..7df80670bea18 100644 --- a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java +++ b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java @@ -388,28 +388,50 @@ protected BytesRef indexedValueForSearch(Object value) { } @Override - public Query termsQuery(List values, QueryShardContext context) { + public Query termsQuery(List values, QueryShardContext context, RewriteOverride rewriteOverride) { failIfNotIndexedAndNoDocValues(); - // has index and doc_values enabled - if (isSearchable() && hasDocValues()) { - BytesRef[] bytesRefs = new BytesRef[values.size()]; - for (int i = 0; i < bytesRefs.length; i++) { - bytesRefs[i] = indexedValueForSearch(values.get(i)); - } - Query indexQuery = new TermInSetQuery(name(), bytesRefs); - Query dvQuery = new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, name(), bytesRefs); - return new IndexOrDocValuesQuery(indexQuery, dvQuery); + if (rewriteOverride == null) { + rewriteOverride = RewriteOverride.DEFAULT; } - // if we only have doc_values enabled, we construct a new query with doc_values re-written - if (hasDocValues()) { - BytesRef[] bytesRefs = new BytesRef[values.size()]; - for (int i = 0; i < bytesRefs.length; i++) { - bytesRefs[i] = indexedValueForSearch(values.get(i)); - } - return new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, name(), bytesRefs); + Query query = null; + switch (rewriteOverride) { + case DEFAULT: + // has index and doc_values enabled + if (isSearchable() && hasDocValues()) { + BytesRef[] bytesRefs = new BytesRef[values.size()]; + for (int i = 0; i < bytesRefs.length; i++) { + bytesRefs[i] = indexedValueForSearch(values.get(i)); + } + Query indexQuery = new TermInSetQuery(name(), bytesRefs); + Query dvQuery = new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, name(), bytesRefs); + query = new IndexOrDocValuesQuery(indexQuery, dvQuery); + } + // if we only have doc_values enabled, we construct a new query with doc_values re-written + else if (hasDocValues()) { + BytesRef[] bytesRefs = new BytesRef[values.size()]; + for (int i = 0; i < bytesRefs.length; i++) { + bytesRefs[i] = indexedValueForSearch(values.get(i)); + } + query = new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, name(), bytesRefs); + } else { + query = super.termsQuery(values, context); + } + break; + case INDEX_ONLY: + failIfNotIndexed(); + query = super.termsQuery(values, context); + break; + case DOC_VALUES_ONLY: + failIfNoDocValues(); + BytesRef[] bytesRefs = new BytesRef[values.size()]; + for (int i = 0; i < bytesRefs.length; i++) { + bytesRefs[i] = indexedValueForSearch(values.get(i)); + } + query = new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, name(), bytesRefs); + break; } - // has index enabled, we're going to return the query as is - return super.termsQuery(values, context); + + return query; } @Override diff --git a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java index 66d4654e543a2..291f1f26054fa 100644 --- a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java @@ -230,6 +230,14 @@ public Query termQueryCaseInsensitive(Object value, @Nullable QueryShardContext ); } + public Query termsQuery(List values, @Nullable QueryShardContext context, @Nullable RewriteOverride rewriteOverride) { + BooleanQuery.Builder builder = new BooleanQuery.Builder(); + for (Object value : values) { + builder.add(termQuery(value, context), Occur.SHOULD); + } + return new ConstantScoreQuery(builder.build()); + } + /** Build a constant-scoring query that matches all values. The default implementation uses a * {@link ConstantScoreQuery} around a {@link BooleanQuery} whose {@link Occur#SHOULD} clauses * are generated with {@link #termQuery}. */ diff --git a/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java b/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java new file mode 100644 index 0000000000000..966d8feebab17 --- /dev/null +++ b/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java @@ -0,0 +1,29 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.index.mapper; + +import org.opensearch.common.annotation.PublicApi; + +/* +* A custom rewrite override for a query. Default executes the query as is and other values determine which structure to use at run-time. +* +* @opensearch.internal +* */ +@PublicApi(since = "2.17.0") +public enum RewriteOverride { + + // don't override the rewrite, use default + DEFAULT, + + // use index structure + INDEX_ONLY, + + // use doc_values structure + DOC_VALUES_ONLY +} diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index ac0ca3919ea38..b868a2946efcc 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -41,7 +41,9 @@ import org.opensearch.client.Client; import org.opensearch.common.SetOnce; import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.common.xcontent.LoggingDeprecationHandler; import org.opensearch.common.xcontent.support.XContentMapValues; +import org.opensearch.core.ParseField; import org.opensearch.core.action.ActionListener; import org.opensearch.core.common.ParsingException; import org.opensearch.core.common.Strings; @@ -53,6 +55,8 @@ import org.opensearch.index.IndexSettings; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; +import org.opensearch.index.mapper.RewriteOverride; +import org.opensearch.index.query.support.QueryParsers; import org.opensearch.indices.TermsLookup; import java.io.IOException; @@ -82,6 +86,10 @@ public class TermsQueryBuilder extends AbstractQueryBuilder { private final TermsLookup termsLookup; private final Supplier> supplier; + private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); + + private String rewrite_override; + public TermsQueryBuilder(String fieldName, TermsLookup termsLookup) { this(fieldName, null, termsLookup); } @@ -201,6 +209,7 @@ public TermsQueryBuilder(StreamInput in) throws IOException { super(in); fieldName = in.readString(); termsLookup = in.readOptionalWriteable(TermsLookup::new); + rewrite_override = in.readOptionalString(); values = (List) in.readGenericValue(); this.supplier = null; } @@ -212,6 +221,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { } out.writeString(fieldName); out.writeOptionalWriteable(termsLookup); + out.writeOptionalString(rewrite_override); out.writeGenericValue(values); } @@ -227,6 +237,15 @@ public TermsLookup termsLookup() { return this.termsLookup; } + public TermsQueryBuilder rewrite_override(String rewrite_override) { + this.rewrite_override = rewrite_override; + return this; + } + + public String rewrite_override() { + return this.rewrite_override; + } + private static final Set> INTEGER_TYPES = new HashSet<>( Arrays.asList(Byte.class, Short.class, Integer.class, Long.class) ); @@ -352,6 +371,9 @@ public Object get(int index) { @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(NAME); + if (rewrite_override != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + } if (this.termsLookup != null) { builder.startObject(fieldName); termsLookup.toXContent(builder, params); @@ -368,6 +390,8 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc List values = null; TermsLookup termsLookup = null; + String rewrite_override = null; + String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; @@ -401,6 +425,13 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc } fieldName = currentFieldName; termsLookup = TermsLookup.parseTermsLookup(parser); + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { + rewrite_override = parser.textOrNull(); + } + } } else if (token.isValue()) { if (AbstractQueryBuilder.BOOST_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { boost = parser.floatValue(); @@ -430,7 +461,7 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc ); } - return new TermsQueryBuilder(fieldName, values, termsLookup).boost(boost).queryName(queryName); + return new TermsQueryBuilder(fieldName, values, termsLookup).boost(boost).queryName(queryName).rewrite_override(rewrite_override); } static List parseValues(XContentParser parser) throws IOException { @@ -473,7 +504,12 @@ protected Query doToQuery(QueryShardContext context) throws IOException { if (fieldType == null) { throw new IllegalStateException("Rewrite first"); } - return fieldType.termsQuery(values, context); + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + return fieldType.termsQuery(values, context, rewriteOverride); } private void fetch(TermsLookup termsLookup, Client client, ActionListener> actionListener) { @@ -491,7 +527,7 @@ private void fetch(TermsLookup termsLookup, Client client, ActionListener Date: Tue, 30 Jul 2024 17:25:08 -0700 Subject: [PATCH 02/23] Fix field parsing in fromXContent Signed-off-by: Harsha Vamsi Kalluri --- .../org/opensearch/index/query/TermsQueryBuilder.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index b868a2946efcc..81eacc6be414f 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -110,6 +110,7 @@ public TermsQueryBuilder(String fieldName, TermsLookup termsLookup) { this.fieldName = fieldName; this.values = values == null ? null : convert(values); this.termsLookup = termsLookup; + this.rewrite_override = rewrite_override; this.supplier = null; } @@ -425,18 +426,13 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc } fieldName = currentFieldName; termsLookup = TermsLookup.parseTermsLookup(parser); - while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { - if (token == XContentParser.Token.FIELD_NAME) { - currentFieldName = parser.currentName(); - } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { - rewrite_override = parser.textOrNull(); - } - } } else if (token.isValue()) { if (AbstractQueryBuilder.BOOST_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { boost = parser.floatValue(); } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); + } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { + rewrite_override = parser.textOrNull(); } else { throw new ParsingException( parser.getTokenLocation(), From b3b17a6dca67bc0bdf863758524c48e96b25a7b7 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Tue, 30 Jul 2024 17:38:41 -0700 Subject: [PATCH 03/23] Remove un-necessary variable Signed-off-by: Harsha Vamsi Kalluri --- .../main/java/org/opensearch/index/query/TermsQueryBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index 81eacc6be414f..c2813ed0976fe 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -110,7 +110,6 @@ public TermsQueryBuilder(String fieldName, TermsLookup termsLookup) { this.fieldName = fieldName; this.values = values == null ? null : convert(values); this.termsLookup = termsLookup; - this.rewrite_override = rewrite_override; this.supplier = null; } From c978ea3a9cd172a16749bd71735bcb31888d0ebd Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Wed, 31 Jul 2024 16:31:52 -0700 Subject: [PATCH 04/23] Fix term query tests Signed-off-by: Harsha Vamsi Kalluri --- .../index/query/TermsQueryBuilder.java | 36 +++++++++++++------ .../index/mapper/KeywordFieldTypeTests.java | 8 ++--- .../index/query/TermsQueryBuilderTests.java | 3 +- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index c2813ed0976fe..f2aa9f70bd605 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -37,6 +37,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; +import org.opensearch.Version; import org.opensearch.action.get.GetRequest; import org.opensearch.client.Client; import org.opensearch.common.SetOnce; @@ -202,6 +203,20 @@ private TermsQueryBuilder(String fieldName, Supplier> supplier) { this.supplier = supplier; } + + private TermsQueryBuilder(String fieldName, Iterable values, String rewrite_override) { + this(fieldName, values); + this.rewrite_override = rewrite_override; + } + + + private TermsQueryBuilder(String fieldName, Supplier> supplier, String rewrite_override) { + this(fieldName, supplier); + this.rewrite_override = rewrite_override; + } + + + /** * Read from a stream. */ @@ -209,9 +224,11 @@ public TermsQueryBuilder(StreamInput in) throws IOException { super(in); fieldName = in.readString(); termsLookup = in.readOptionalWriteable(TermsLookup::new); - rewrite_override = in.readOptionalString(); values = (List) in.readGenericValue(); this.supplier = null; + if (in.getVersion().after(Version.V_2_16_0)){ + rewrite_override = in.readOptionalString(); + } } @Override @@ -221,8 +238,10 @@ protected void doWriteTo(StreamOutput out) throws IOException { } out.writeString(fieldName); out.writeOptionalWriteable(termsLookup); - out.writeOptionalString(rewrite_override); out.writeGenericValue(values); + if (out.getVersion().after(Version.V_2_16_0)){ + out.writeOptionalString(rewrite_override); + } } public String fieldName() { @@ -499,12 +518,7 @@ protected Query doToQuery(QueryShardContext context) throws IOException { if (fieldType == null) { throw new IllegalStateException("Rewrite first"); } - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( - rewrite_override, - RewriteOverride.DEFAULT, - LoggingDeprecationHandler.INSTANCE - ); - return fieldType.termsQuery(values, context, rewriteOverride); + return fieldType.termsQuery(values, context); } private void fetch(TermsLookup termsLookup, Client client, ActionListener> actionListener) { @@ -537,14 +551,14 @@ protected boolean doEquals(TermsQueryBuilder other) { @Override protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { if (supplier != null) { - return supplier.get() == null ? this : new TermsQueryBuilder(this.fieldName, supplier.get()); + return supplier.get() == null ? this : new TermsQueryBuilder(this.fieldName, supplier.get(), rewrite_override); } else if (this.termsLookup != null) { SetOnce> supplier = new SetOnce<>(); queryRewriteContext.registerAsyncAction((client, listener) -> fetch(termsLookup, client, ActionListener.map(listener, list -> { supplier.set(list); return null; }))); - return new TermsQueryBuilder(this.fieldName, supplier::get); + return new TermsQueryBuilder(this.fieldName, supplier::get, rewrite_override); } if (values == null || values.isEmpty()) { @@ -560,7 +574,7 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { // This logic is correct for all field types, but by only applying it to constant // fields we also have the guarantee that it doesn't perform I/O, which is important // since rewrites might happen on a network thread. - Query query = fieldType.termsQuery(values, context, null); + Query query = fieldType.termsQuery(values, context); if (query instanceof MatchAllDocsQuery) { return new MatchAllQueryBuilder(); } else if (query instanceof MatchNoDocsQuery) { diff --git a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java index b10035f54a0c0..7426b65657860 100644 --- a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java +++ b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java @@ -136,20 +136,20 @@ public void testTermsQuery() { new TermInSetQuery("field", terms), new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, "field", terms) ); - assertEquals(expected, ft.termsQuery(Arrays.asList("foo", "bar"), null)); + assertEquals(expected, ft.termsQuery(Arrays.asList("foo", "bar"), null, RewriteOverride.DEFAULT)); MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); Query expectedIndex = new TermInSetQuery("field", terms); - assertEquals(expectedIndex, onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), null)); + assertEquals(expectedIndex, onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), null, RewriteOverride.DEFAULT)); MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); Query expectedDocValues = new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, "field", terms); - assertEquals(expectedDocValues, onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), null)); + assertEquals(expectedDocValues, onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), null, RewriteOverride.DEFAULT)); MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"), null) + () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"), null, RewriteOverride.DEFAULT) ); assertEquals( "Cannot search on field [field] since it is both not indexed, and does not have doc_values " + "enabled.", diff --git a/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java index 97f372dc04a1b..1b74b02c16994 100644 --- a/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java @@ -53,6 +53,7 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.get.GetResult; +import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.indices.TermsLookup; import org.opensearch.test.AbstractQueryTestCase; import org.hamcrest.CoreMatchers; @@ -363,7 +364,7 @@ public void testConversion() { } public void testRewriteIndexQueryToMatchNone() throws IOException { - TermsQueryBuilder query = new TermsQueryBuilder("_index", "does_not_exist", "also_does_not_exist"); + TermsQueryBuilder query = new TermsQueryBuilder("_index", "does_not_exist", "also_does_not_exist", RewriteOverride.DEFAULT); QueryShardContext queryShardContext = createShardContext(); QueryBuilder rewritten = query.rewrite(queryShardContext); assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class)); From 31e4964e240ea79bd7003dc12b71a039d63d221d Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Wed, 31 Jul 2024 16:46:06 -0700 Subject: [PATCH 05/23] Spotless Signed-off-by: Harsha Vamsi Kalluri --- .../org/opensearch/index/query/TermsQueryBuilder.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index f2aa9f70bd605..08d8b3a4d3034 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -42,7 +42,6 @@ import org.opensearch.client.Client; import org.opensearch.common.SetOnce; import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.common.xcontent.LoggingDeprecationHandler; import org.opensearch.common.xcontent.support.XContentMapValues; import org.opensearch.core.ParseField; import org.opensearch.core.action.ActionListener; @@ -56,8 +55,6 @@ import org.opensearch.index.IndexSettings; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; -import org.opensearch.index.mapper.RewriteOverride; -import org.opensearch.index.query.support.QueryParsers; import org.opensearch.indices.TermsLookup; import java.io.IOException; @@ -203,20 +200,16 @@ private TermsQueryBuilder(String fieldName, Supplier> supplier) { this.supplier = supplier; } - private TermsQueryBuilder(String fieldName, Iterable values, String rewrite_override) { this(fieldName, values); this.rewrite_override = rewrite_override; } - private TermsQueryBuilder(String fieldName, Supplier> supplier, String rewrite_override) { this(fieldName, supplier); this.rewrite_override = rewrite_override; } - - /** * Read from a stream. */ @@ -226,7 +219,7 @@ public TermsQueryBuilder(StreamInput in) throws IOException { termsLookup = in.readOptionalWriteable(TermsLookup::new); values = (List) in.readGenericValue(); this.supplier = null; - if (in.getVersion().after(Version.V_2_16_0)){ + if (in.getVersion().after(Version.V_2_16_0)) { rewrite_override = in.readOptionalString(); } } @@ -239,7 +232,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(fieldName); out.writeOptionalWriteable(termsLookup); out.writeGenericValue(values); - if (out.getVersion().after(Version.V_2_16_0)){ + if (out.getVersion().after(Version.V_2_16_0)) { out.writeOptionalString(rewrite_override); } } From 07e3caa276f54d05bee7720626e59d7836a306a3 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Wed, 31 Jul 2024 16:58:27 -0700 Subject: [PATCH 06/23] Spotless Signed-off-by: Harsha Vamsi Kalluri --- .../search/aggregations/bucket/BucketsAggregator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/org/opensearch/search/aggregations/bucket/BucketsAggregator.java b/server/src/main/java/org/opensearch/search/aggregations/bucket/BucketsAggregator.java index eef427754f535..c85c61f6da29e 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/bucket/BucketsAggregator.java +++ b/server/src/main/java/org/opensearch/search/aggregations/bucket/BucketsAggregator.java @@ -76,7 +76,7 @@ public abstract class BucketsAggregator extends AggregatorBase { public BucketsAggregator( String name, - AggregatorFactories factories, + AggregatorFactories factories, SearchContext context, Aggregator parent, CardinalityUpperBound bucketCardinality, From 67425be94631a04eeec0390142fb98abfe06c56f Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Mon, 5 Aug 2024 16:02:04 -0700 Subject: [PATCH 07/23] Add rewrite_override to more queries Signed-off-by: Harsha Vamsi Kalluri --- .../index/mapper/KeywordFieldMapper.java | 340 ++++++++++++------ .../index/mapper/MappedFieldType.java | 57 ++- .../index/mapper/SimpleMappedFieldType.java | 4 + .../index/query/PrefixQueryBuilder.java | 30 +- .../index/query/RangeQueryBuilder.java | 31 +- .../index/query/RegexpQueryBuilder.java | 29 +- .../index/query/TermsQueryBuilder.java | 4 - .../index/query/WildcardQueryBuilder.java | 30 +- 8 files changed, 403 insertions(+), 122 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java index 7df80670bea18..d4020a3937208 100644 --- a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java +++ b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java @@ -388,7 +388,7 @@ protected BytesRef indexedValueForSearch(Object value) { } @Override - public Query termsQuery(List values, QueryShardContext context, RewriteOverride rewriteOverride) { + public Query termsQuery(List values, RewriteOverride rewriteOverride, QueryShardContext context) { failIfNotIndexedAndNoDocValues(); if (rewriteOverride == null) { rewriteOverride = RewriteOverride.DEFAULT; @@ -438,6 +438,7 @@ else if (hasDocValues()) { public Query prefixQuery( String value, @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, boolean caseInsensitive, QueryShardContext context ) { @@ -450,21 +451,49 @@ public Query prefixQuery( ); } failIfNotIndexedAndNoDocValues(); - if (isSearchable() && hasDocValues()) { - Query indexQuery = super.prefixQuery(value, method, caseInsensitive, context); - Query dvQuery = super.prefixQuery(value, MultiTermQuery.DOC_VALUES_REWRITE, caseInsensitive, context); - return new IndexOrDocValuesQuery(indexQuery, dvQuery); + if (rewriteOverride == null) { + rewriteOverride = RewriteOverride.DEFAULT; } - if (hasDocValues()) { - if (caseInsensitive) { - return AutomatonQueries.caseInsensitivePrefixQuery( - (new Term(name(), indexedValueForSearch(value))), - MultiTermQuery.DOC_VALUES_REWRITE - ); - } - return new PrefixQuery(new Term(name(), indexedValueForSearch(value)), MultiTermQuery.DOC_VALUES_REWRITE); + Query query = null; + switch (rewriteOverride) { + case DEFAULT: + if (isSearchable() && hasDocValues()) { + Query indexQuery = super.prefixQuery(value, method, caseInsensitive, context); + Query dvQuery = super.prefixQuery(value, MultiTermQuery.DOC_VALUES_REWRITE, caseInsensitive, context); + query = new IndexOrDocValuesQuery(indexQuery, dvQuery); + } + else if (hasDocValues()) { + if (caseInsensitive) { + return AutomatonQueries.caseInsensitivePrefixQuery( + (new Term(name(), indexedValueForSearch(value))), + MultiTermQuery.DOC_VALUES_REWRITE + ); + } + query = new PrefixQuery(new Term(name(), indexedValueForSearch(value)), MultiTermQuery.DOC_VALUES_REWRITE); + } + else{ + query = super.prefixQuery(value, method, caseInsensitive, context); + } + break; + case INDEX_ONLY: + failIfNotIndexed(); + query = super.prefixQuery(value, method, caseInsensitive, context); + break; + case DOC_VALUES_ONLY: + failIfNoDocValues(); + if (caseInsensitive) { + query = AutomatonQueries.caseInsensitivePrefixQuery( + (new Term(name(), indexedValueForSearch(value))), + MultiTermQuery.DOC_VALUES_REWRITE + ); + } + else { + query = new PrefixQuery(new Term(name(), indexedValueForSearch(value)), MultiTermQuery.DOC_VALUES_REWRITE); + } + break; } - return super.prefixQuery(value, method, caseInsensitive, context); + + return query; } @Override @@ -474,6 +503,7 @@ public Query regexpQuery( int matchFlags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, QueryShardContext context ) { if (context.allowExpensiveQueries() == false) { @@ -482,33 +512,59 @@ public Query regexpQuery( ); } failIfNotIndexedAndNoDocValues(); - if (isSearchable() && hasDocValues()) { - Query indexQuery = super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); - Query dvQuery = super.regexpQuery( - value, - syntaxFlags, - matchFlags, - maxDeterminizedStates, - MultiTermQuery.DOC_VALUES_REWRITE, - context - ); - return new IndexOrDocValuesQuery(indexQuery, dvQuery); + if (rewriteOverride == null) { + rewriteOverride = RewriteOverride.DEFAULT; } - if (hasDocValues()) { - return new RegexpQuery( - new Term(name(), indexedValueForSearch(value)), - syntaxFlags, - matchFlags, - RegexpQuery.DEFAULT_PROVIDER, - maxDeterminizedStates, - MultiTermQuery.DOC_VALUES_REWRITE - ); + Query query = null; + switch(rewriteOverride) { + case DEFAULT: + if (isSearchable() && hasDocValues()) { + Query indexQuery = super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); + Query dvQuery = super.regexpQuery( + value, + syntaxFlags, + matchFlags, + maxDeterminizedStates, + MultiTermQuery.DOC_VALUES_REWRITE, + context + ); + query = new IndexOrDocValuesQuery(indexQuery, dvQuery); + } + else if (hasDocValues()) { + query = new RegexpQuery( + new Term(name(), indexedValueForSearch(value)), + syntaxFlags, + matchFlags, + RegexpQuery.DEFAULT_PROVIDER, + maxDeterminizedStates, + MultiTermQuery.DOC_VALUES_REWRITE + ); + } + else { + query = super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); + } + break; + case INDEX_ONLY: + failIfNotIndexed(); + query = super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); + break; + case DOC_VALUES_ONLY: + failIfNoDocValues(); + query = new RegexpQuery( + new Term(name(), indexedValueForSearch(value)), + syntaxFlags, + matchFlags, + RegexpQuery.DEFAULT_PROVIDER, + maxDeterminizedStates, + MultiTermQuery.DOC_VALUES_REWRITE + ); + break; } - return super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); + return query; } @Override - public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, QueryShardContext context) { + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, RewriteOverride rewriteOverride, QueryShardContext context) { if (context.allowExpensiveQueries() == false) { throw new OpenSearchException( "[range] queries on [text] or [keyword] fields cannot be executed when '" @@ -517,41 +573,67 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower ); } failIfNotIndexedAndNoDocValues(); - if (isSearchable() && hasDocValues()) { - Query indexQuery = new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper - ); - Query dvQuery = new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper, - MultiTermQuery.DOC_VALUES_REWRITE - ); - return new IndexOrDocValuesQuery(indexQuery, dvQuery); + if (rewriteOverride == null) { + rewriteOverride = RewriteOverride.DEFAULT; } - if (hasDocValues()) { - return new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper, - MultiTermQuery.DOC_VALUES_REWRITE - ); + Query query = null; + switch (rewriteOverride) { + case DEFAULT: + if (isSearchable() && hasDocValues()) { + Query indexQuery = new TermRangeQuery( + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper + ); + Query dvQuery = new TermRangeQuery( + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper, + MultiTermQuery.DOC_VALUES_REWRITE + ); + query = new IndexOrDocValuesQuery(indexQuery, dvQuery); + } + else if (hasDocValues()) { + query = new TermRangeQuery( + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper, + MultiTermQuery.DOC_VALUES_REWRITE + ); + } + else { + query = super.rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context); + } + break; + case INDEX_ONLY: + failIfNotIndexed(); + query = new TermRangeQuery( + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper + ); + break; + case DOC_VALUES_ONLY: + failIfNoDocValues(); + query = new TermRangeQuery( + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper, + MultiTermQuery.DOC_VALUES_REWRITE + ); + break; } - return new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper - ); + return query; } @Override @@ -562,6 +644,7 @@ public Query fuzzyQuery( int maxExpansions, boolean transpositions, @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, QueryShardContext context ) { failIfNotIndexedAndNoDocValues(); @@ -570,36 +653,63 @@ public Query fuzzyQuery( "[fuzzy] queries cannot be executed when '" + ALLOW_EXPENSIVE_QUERIES.getKey() + "' is set to " + "false." ); } - if (isSearchable() && hasDocValues()) { - Query indexQuery = super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); - Query dvQuery = super.fuzzyQuery( - value, - fuzziness, - prefixLength, - maxExpansions, - transpositions, - MultiTermQuery.DOC_VALUES_REWRITE, - context - ); - return new IndexOrDocValuesQuery(indexQuery, dvQuery); + if (rewriteOverride == null) { + rewriteOverride = RewriteOverride.DEFAULT; } - if (hasDocValues()) { - return new FuzzyQuery( - new Term(name(), indexedValueForSearch(value)), - fuzziness.asDistance(BytesRefs.toString(value)), - prefixLength, - maxExpansions, - transpositions, - MultiTermQuery.DOC_VALUES_REWRITE - ); + Query query = null; + switch (rewriteOverride) { + case DEFAULT: + if (isSearchable() && hasDocValues()) { + Query indexQuery = super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); + Query dvQuery = super.fuzzyQuery( + value, + fuzziness, + prefixLength, + maxExpansions, + transpositions, + MultiTermQuery.DOC_VALUES_REWRITE, + context + ); + query = new IndexOrDocValuesQuery(indexQuery, dvQuery); + } + else if (hasDocValues()) { + query = new FuzzyQuery( + new Term(name(), indexedValueForSearch(value)), + fuzziness.asDistance(BytesRefs.toString(value)), + prefixLength, + maxExpansions, + transpositions, + MultiTermQuery.DOC_VALUES_REWRITE + ); + } + else { + query = super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); + } + break; + case INDEX_ONLY: + failIfNotIndexed(); + query = super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); + break; + case DOC_VALUES_ONLY: + failIfNoDocValues(); + query = new FuzzyQuery( + new Term(name(), indexedValueForSearch(value)), + fuzziness.asDistance(BytesRefs.toString(value)), + prefixLength, + maxExpansions, + transpositions, + MultiTermQuery.DOC_VALUES_REWRITE + ); + break; } - return super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, context); + return query; } @Override public Query wildcardQuery( String value, @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, boolean caseInsensitive, QueryShardContext context ) { @@ -612,21 +722,43 @@ public Query wildcardQuery( // keyword field types are always normalized, so ignore case sensitivity and force normalize the // wildcard // query text - if (isSearchable() && hasDocValues()) { - Query indexQuery = super.wildcardQuery(value, method, caseInsensitive, true, context); - Query dvQuery = super.wildcardQuery(value, MultiTermQuery.DOC_VALUES_REWRITE, caseInsensitive, true, context); - return new IndexOrDocValuesQuery(indexQuery, dvQuery); + if (rewriteOverride == null) { + rewriteOverride = RewriteOverride.DEFAULT; } - if (hasDocValues()) { - Term term; - value = normalizeWildcardPattern(name(), value, getTextSearchInfo().getSearchAnalyzer()); - term = new Term(name(), value); - if (caseInsensitive) { - return AutomatonQueries.caseInsensitiveWildcardQuery(term, method); - } - return new WildcardQuery(term, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.DOC_VALUES_REWRITE); + Query query = null; + switch (rewriteOverride) { + case DEFAULT: + if (isSearchable() && hasDocValues()) { + Query indexQuery = super.wildcardQuery(value, method, caseInsensitive, true, context); + Query dvQuery = super.wildcardQuery(value, MultiTermQuery.DOC_VALUES_REWRITE, caseInsensitive, true, context); + query = new IndexOrDocValuesQuery(indexQuery, dvQuery); + } + if (hasDocValues()) { + Term term; + value = normalizeWildcardPattern(name(), value, getTextSearchInfo().getSearchAnalyzer()); + term = new Term(name(), value); + if (caseInsensitive) { + return AutomatonQueries.caseInsensitiveWildcardQuery(term, method); + } + query = new WildcardQuery(term, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.DOC_VALUES_REWRITE); + } + break; + case INDEX_ONLY: + failIfNotIndexed(); + query = super.wildcardQuery(value, method, caseInsensitive, true, context); + break; + case DOC_VALUES_ONLY: + failIfNoDocValues(); + Term term; + value = normalizeWildcardPattern(name(), value, getTextSearchInfo().getSearchAnalyzer()); + term = new Term(name(), value); + if (caseInsensitive) { + return AutomatonQueries.caseInsensitiveWildcardQuery(term, method); + } + query = new WildcardQuery(term, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.DOC_VALUES_REWRITE); + break; } - return super.wildcardQuery(value, method, caseInsensitive, true, context); + return query; } } diff --git a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java index 291f1f26054fa..1d26cc30270d6 100644 --- a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java @@ -230,7 +230,7 @@ public Query termQueryCaseInsensitive(Object value, @Nullable QueryShardContext ); } - public Query termsQuery(List values, @Nullable QueryShardContext context, @Nullable RewriteOverride rewriteOverride) { + public Query termsQuery(List values, @Nullable RewriteOverride rewriteOverride, @Nullable QueryShardContext context) { BooleanQuery.Builder builder = new BooleanQuery.Builder(); for (Object value : values) { builder.add(termQuery(value, context), Occur.SHOULD); @@ -294,6 +294,34 @@ public Query fuzzyQuery( ); } + public Query fuzzyQuery( + Object value, + Fuzziness fuzziness, + int prefixLength, + int maxExpansions, + boolean transpositions, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + QueryShardContext context + ) { + throw new IllegalArgumentException( + "Can only use fuzzy queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" + ); + } + + public Query prefixQuery( + String value, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + boolean caseInsensitve, + QueryShardContext context + ) { + throw new QueryShardException( + context, + "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" + ); + } + // Case sensitive form of prefix query public final Query prefixQuery(String value, @Nullable MultiTermQuery.RewriteMethod method, QueryShardContext context) { return prefixQuery(value, method, false, context); @@ -328,6 +356,18 @@ public Query wildcardQuery( "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" ); } + public Query wildcardQuery( + String value, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + boolean caseInsensitve, + QueryShardContext context + ) { + throw new QueryShardException( + context, + "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" + ); + } /** always normalizes the wildcard pattern to lowercase */ public Query normalizedWildcardQuery(String value, @Nullable MultiTermQuery.RewriteMethod method, QueryShardContext context) { @@ -351,6 +391,21 @@ public Query regexpQuery( ); } + public Query regexpQuery( + String value, + int syntaxFlags, + int matchFlags, + int maxDeterminizedStates, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + QueryShardContext context + ) { + throw new QueryShardException( + context, + "Can only use regexp queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" + ); + } + public Query existsQuery(QueryShardContext context) { if (hasDocValues()) { return new DocValuesFieldExistsQuery(name()); diff --git a/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java index 7ea5d49e234a5..16cde2b04612b 100644 --- a/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java @@ -86,4 +86,8 @@ protected Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLo throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support range queries"); } + protected Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper,RewriteOverride rewriteOverride, QueryShardContext context) { + throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support range queries"); + } + } diff --git a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java index ffc748bffb66e..327dc655b0595 100644 --- a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java @@ -36,6 +36,7 @@ import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.Query; +import org.opensearch.Version; import org.opensearch.common.xcontent.LoggingDeprecationHandler; import org.opensearch.core.ParseField; import org.opensearch.core.common.ParsingException; @@ -62,6 +63,10 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder private static final ParseField PREFIX_FIELD = new ParseField("value"); private static final ParseField REWRITE_FIELD = new ParseField("rewrite"); + private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); + + private String rewrite_override; + private final String fieldName; private final String value; @@ -98,6 +103,9 @@ public PrefixQueryBuilder(StreamInput in) throws IOException { value = in.readString(); rewrite = in.readOptionalString(); caseInsensitive = in.readBoolean(); + if (in.getVersion().after(Version.V_2_16_0)) { + rewrite_override = in.readOptionalString(); + } } @Override @@ -106,6 +114,9 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(value); out.writeOptionalString(rewrite); out.writeBoolean(caseInsensitive); + if (out.getVersion().after(Version.V_2_16_0)) { + out.writeOptionalString(rewrite_override); + } } @Override @@ -131,6 +142,11 @@ public PrefixQueryBuilder rewrite(String rewrite) { return this; } + public PrefixQueryBuilder rewrite_override(String rewrite_override) { + this.rewrite_override = rewrite_override; + return this; + } + public String rewrite() { return this.rewrite; } @@ -146,6 +162,9 @@ public void doXContent(XContentBuilder builder, Params params) throws IOExceptio if (caseInsensitive != DEFAULT_CASE_INSENSITIVITY) { builder.field(CASE_INSENSITIVE_FIELD.getPreferredName(), caseInsensitive); } + if (rewrite_override != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + } printBoostAndQueryName(builder); builder.endObject(); builder.endObject(); @@ -155,6 +174,8 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx String fieldName = null; String value = null; String rewrite = null; + String rewrite_override = null; + String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; @@ -181,7 +202,9 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx rewrite = parser.textOrNull(); } else if (CASE_INSENSITIVE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { caseInsensitive = parser.booleanValue(); - } else { + } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { + rewrite_override = parser.textOrNull(); + }else { throw new ParsingException( parser.getTokenLocation(), "[prefix] query does not support [" + currentFieldName + "]" @@ -196,7 +219,7 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx } } - return new PrefixQueryBuilder(fieldName, value).rewrite(rewrite).boost(boost).queryName(queryName).caseInsensitive(caseInsensitive); + return new PrefixQueryBuilder(fieldName, value).rewrite(rewrite).boost(boost).queryName(queryName).caseInsensitive(caseInsensitive).rewrite_override(rewrite_override); } @Override @@ -242,7 +265,7 @@ protected Query doToQuery(QueryShardContext context) throws IOException { @Override protected final int doHashCode() { - return Objects.hash(fieldName, value, rewrite, caseInsensitive); + return Objects.hash(fieldName, value, rewrite, caseInsensitive, rewrite_override); } @Override @@ -250,6 +273,7 @@ protected boolean doEquals(PrefixQueryBuilder other) { return Objects.equals(fieldName, other.fieldName) && Objects.equals(value, other.value) && Objects.equals(rewrite, other.rewrite) + && Objects.equals(rewrite_override, other.rewrite_override) && Objects.equals(caseInsensitive, other.caseInsensitive); } } diff --git a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java index fdbef2c732361..36a8f425a2ccd 100644 --- a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java @@ -35,6 +35,7 @@ import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; +import org.opensearch.Version; import org.opensearch.common.geo.ShapeRelation; import org.opensearch.common.time.DateFormatter; import org.opensearch.common.time.DateMathParser; @@ -75,6 +76,8 @@ public class RangeQueryBuilder extends AbstractQueryBuilder i private static final ParseField TIME_ZONE_FIELD = new ParseField("time_zone"); private static final ParseField FORMAT_FIELD = new ParseField("format"); private static final ParseField RELATION_FIELD = new ParseField("relation"); + private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); + private final String fieldName; private Object from; @@ -85,6 +88,8 @@ public class RangeQueryBuilder extends AbstractQueryBuilder i private String format; private ShapeRelation relation; + private String rewrite_override; + /** * A Query that matches documents within an range of terms. * @@ -116,6 +121,9 @@ public RangeQueryBuilder(StreamInput in) throws IOException { throw new IllegalArgumentException("[range] query does not support relation [" + relationString + "]"); } } + if (in.getVersion().after(Version.V_2_16_0)) { + rewrite_override = in.readOptionalString(); + } } private boolean isRelationAllowed(ShapeRelation relation) { @@ -136,6 +144,9 @@ protected void doWriteTo(StreamOutput out) throws IOException { relationString = this.relation.getRelationName(); } out.writeOptionalString(relationString); + if (out.getVersion().after(Version.V_2_16_0)) { + out.writeOptionalString(rewrite_override); + } } /** @@ -271,6 +282,11 @@ public RangeQueryBuilder timeZone(String timeZone) { return this; } + public RangeQueryBuilder rewrite_override(String rewrite_override) { + this.rewrite_override = rewrite_override; + return this; + } + /** * In case of date field, gets the from/to fields timezone adjustment */ @@ -344,6 +360,9 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep if (relation != null) { builder.field(RELATION_FIELD.getPreferredName(), relation.getRelationName()); } + if (rewrite_override != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + } printBoostAndQueryName(builder); builder.endObject(); builder.endObject(); @@ -360,6 +379,8 @@ public static RangeQueryBuilder fromXContent(XContentParser parser) throws IOExc String queryName = null; String format = null; String relation = null; + String rewrite_override = null; + String currentFieldName = null; XContentParser.Token token; @@ -403,7 +424,9 @@ public static RangeQueryBuilder fromXContent(XContentParser parser) throws IOExc relation = parser.text(); } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); - } else { + } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { + rewrite_override = parser.textOrNull(); + }else { throw new ParsingException( parser.getTokenLocation(), "[range] query does not support [" + currentFieldName + "]" @@ -432,6 +455,7 @@ public static RangeQueryBuilder fromXContent(XContentParser parser) throws IOExc if (relation != null) { rangeQuery.relation(relation); } + rangeQuery.rewrite_override(rewrite_override); return rangeQuery; } @@ -529,7 +553,7 @@ protected Query doToQuery(QueryShardContext context) throws IOException { @Override protected int doHashCode() { - return Objects.hash(fieldName, from, to, timeZone, includeLower, includeUpper, format); + return Objects.hash(fieldName, from, to, timeZone, includeLower, includeUpper, format, rewrite_override); } @Override @@ -540,6 +564,7 @@ protected boolean doEquals(RangeQueryBuilder other) { && Objects.equals(timeZone, other.timeZone) && Objects.equals(includeLower, other.includeLower) && Objects.equals(includeUpper, other.includeUpper) - && Objects.equals(format, other.format); + && Objects.equals(format, other.format) + && Objects.equals(rewrite_override, other.rewrite_override); } } diff --git a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java index f0da4d5736c0f..cf65e44902677 100644 --- a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java @@ -38,6 +38,7 @@ import org.apache.lucene.search.RegexpQuery; import org.apache.lucene.util.automaton.Operations; import org.apache.lucene.util.automaton.RegExp; +import org.opensearch.Version; import org.opensearch.common.lucene.BytesRefs; import org.opensearch.common.xcontent.LoggingDeprecationHandler; import org.opensearch.core.ParseField; @@ -73,6 +74,10 @@ public class RegexpQueryBuilder extends AbstractQueryBuilder private static final ParseField REWRITE_FIELD = new ParseField("rewrite"); private static final ParseField VALUE_FIELD = new ParseField("value"); + private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); + + private String rewrite_override; + private final String fieldName; private final String value; @@ -112,6 +117,9 @@ public RegexpQueryBuilder(StreamInput in) throws IOException { maxDeterminizedStates = in.readVInt(); rewrite = in.readOptionalString(); caseInsensitive = in.readBoolean(); + if (in.getVersion().after(Version.V_2_16_0)) { + rewrite_override = in.readOptionalString(); + } } @Override @@ -122,6 +130,9 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeVInt(maxDeterminizedStates); out.writeOptionalString(rewrite); out.writeBoolean(caseInsensitive); + if (out.getVersion().after(Version.V_2_16_0)) { + out.writeOptionalString(rewrite_override); + } } /** Returns the field name used in this query. */ @@ -172,6 +183,11 @@ public boolean caseInsensitive() { return this.caseInsensitive; } + public RegexpQueryBuilder rewrite_override(String rewrite_override) { + this.rewrite_override = rewrite_override; + return this; + } + /** * Sets the regexp maxDeterminizedStates. */ @@ -206,6 +222,9 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep if (rewrite != null) { builder.field(REWRITE_FIELD.getPreferredName(), rewrite); } + if (rewrite_override != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + } printBoostAndQueryName(builder); builder.endObject(); builder.endObject(); @@ -215,6 +234,7 @@ public static RegexpQueryBuilder fromXContent(XContentParser parser) throws IOEx String fieldName = null; String rewrite = null; String value = null; + String rewrite_override = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; int flagsValue = RegexpQueryBuilder.DEFAULT_FLAGS_VALUE; boolean caseInsensitive = DEFAULT_CASE_INSENSITIVITY; @@ -249,7 +269,9 @@ public static RegexpQueryBuilder fromXContent(XContentParser parser) throws IOEx caseInsensitive = parser.booleanValue(); } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); - } else { + } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { + rewrite_override = parser.textOrNull(); + }else { throw new ParsingException( parser.getTokenLocation(), "[regexp] query does not support [" + currentFieldName + "]" @@ -270,6 +292,7 @@ public static RegexpQueryBuilder fromXContent(XContentParser parser) throws IOEx .boost(boost) .queryName(queryName); result.caseInsensitive(caseInsensitive); + result.rewrite_override(rewrite_override); return result; } @@ -323,7 +346,7 @@ protected Query doToQuery(QueryShardContext context) throws QueryShardException, @Override protected int doHashCode() { - return Objects.hash(fieldName, value, syntaxFlagsValue, caseInsensitive, maxDeterminizedStates, rewrite); + return Objects.hash(fieldName, value, syntaxFlagsValue, caseInsensitive, maxDeterminizedStates, rewrite, rewrite_override); } @Override @@ -333,6 +356,6 @@ protected boolean doEquals(RegexpQueryBuilder other) { && Objects.equals(syntaxFlagsValue, other.syntaxFlagsValue) && Objects.equals(caseInsensitive, other.caseInsensitive) && Objects.equals(maxDeterminizedStates, other.maxDeterminizedStates) - && Objects.equals(rewrite, other.rewrite); + && Objects.equals(rewrite, other.rewrite) && Objects.equals(rewrite_override, other.rewrite_override); } } diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index 08d8b3a4d3034..8c03e67700a0f 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -254,10 +254,6 @@ public TermsQueryBuilder rewrite_override(String rewrite_override) { return this; } - public String rewrite_override() { - return this.rewrite_override; - } - private static final Set> INTEGER_TYPES = new HashSet<>( Arrays.asList(Byte.class, Short.class, Integer.class, Long.class) ); diff --git a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java index d1fe4f0ba0264..03007e68b138f 100644 --- a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java @@ -36,6 +36,7 @@ import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.Query; +import org.opensearch.Version; import org.opensearch.common.xcontent.LoggingDeprecationHandler; import org.opensearch.core.ParseField; import org.opensearch.core.common.ParsingException; @@ -67,6 +68,9 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder Date: Mon, 5 Aug 2024 16:03:08 -0700 Subject: [PATCH 08/23] Spotless Signed-off-by: Harsha Vamsi Kalluri --- .../index/mapper/KeywordFieldMapper.java | 152 +++++++++--------- .../index/mapper/MappedFieldType.java | 65 ++++---- .../index/mapper/SimpleMappedFieldType.java | 9 +- .../index/query/PrefixQueryBuilder.java | 11 +- .../index/query/RangeQueryBuilder.java | 6 +- .../index/query/RegexpQueryBuilder.java | 5 +- .../index/query/WildcardQueryBuilder.java | 9 +- .../bucket/BucketsAggregator.java | 2 +- 8 files changed, 134 insertions(+), 125 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java index d4020a3937208..01d33b7ddd9c2 100644 --- a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java +++ b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java @@ -388,7 +388,7 @@ protected BytesRef indexedValueForSearch(Object value) { } @Override - public Query termsQuery(List values, RewriteOverride rewriteOverride, QueryShardContext context) { + public Query termsQuery(List values, RewriteOverride rewriteOverride, QueryShardContext context) { failIfNotIndexedAndNoDocValues(); if (rewriteOverride == null) { rewriteOverride = RewriteOverride.DEFAULT; @@ -461,17 +461,15 @@ public Query prefixQuery( Query indexQuery = super.prefixQuery(value, method, caseInsensitive, context); Query dvQuery = super.prefixQuery(value, MultiTermQuery.DOC_VALUES_REWRITE, caseInsensitive, context); query = new IndexOrDocValuesQuery(indexQuery, dvQuery); - } - else if (hasDocValues()) { + } else if (hasDocValues()) { if (caseInsensitive) { return AutomatonQueries.caseInsensitivePrefixQuery( - (new Term(name(), indexedValueForSearch(value))), - MultiTermQuery.DOC_VALUES_REWRITE + (new Term(name(), indexedValueForSearch(value))), + MultiTermQuery.DOC_VALUES_REWRITE ); } query = new PrefixQuery(new Term(name(), indexedValueForSearch(value)), MultiTermQuery.DOC_VALUES_REWRITE); - } - else{ + } else { query = super.prefixQuery(value, method, caseInsensitive, context); } break; @@ -482,12 +480,11 @@ else if (hasDocValues()) { case DOC_VALUES_ONLY: failIfNoDocValues(); if (caseInsensitive) { - query = AutomatonQueries.caseInsensitivePrefixQuery( - (new Term(name(), indexedValueForSearch(value))), - MultiTermQuery.DOC_VALUES_REWRITE + query = AutomatonQueries.caseInsensitivePrefixQuery( + (new Term(name(), indexedValueForSearch(value))), + MultiTermQuery.DOC_VALUES_REWRITE ); - } - else { + } else { query = new PrefixQuery(new Term(name(), indexedValueForSearch(value)), MultiTermQuery.DOC_VALUES_REWRITE); } break; @@ -516,32 +513,30 @@ public Query regexpQuery( rewriteOverride = RewriteOverride.DEFAULT; } Query query = null; - switch(rewriteOverride) { + switch (rewriteOverride) { case DEFAULT: if (isSearchable() && hasDocValues()) { Query indexQuery = super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); Query dvQuery = super.regexpQuery( - value, - syntaxFlags, - matchFlags, - maxDeterminizedStates, - MultiTermQuery.DOC_VALUES_REWRITE, - context + value, + syntaxFlags, + matchFlags, + maxDeterminizedStates, + MultiTermQuery.DOC_VALUES_REWRITE, + context ); - query = new IndexOrDocValuesQuery(indexQuery, dvQuery); - } - else if (hasDocValues()) { - query = new RegexpQuery( - new Term(name(), indexedValueForSearch(value)), - syntaxFlags, - matchFlags, - RegexpQuery.DEFAULT_PROVIDER, - maxDeterminizedStates, - MultiTermQuery.DOC_VALUES_REWRITE + query = new IndexOrDocValuesQuery(indexQuery, dvQuery); + } else if (hasDocValues()) { + query = new RegexpQuery( + new Term(name(), indexedValueForSearch(value)), + syntaxFlags, + matchFlags, + RegexpQuery.DEFAULT_PROVIDER, + maxDeterminizedStates, + MultiTermQuery.DOC_VALUES_REWRITE ); - } - else { - query = super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); + } else { + query = super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); } break; case INDEX_ONLY: @@ -551,20 +546,27 @@ else if (hasDocValues()) { case DOC_VALUES_ONLY: failIfNoDocValues(); query = new RegexpQuery( - new Term(name(), indexedValueForSearch(value)), - syntaxFlags, - matchFlags, - RegexpQuery.DEFAULT_PROVIDER, - maxDeterminizedStates, - MultiTermQuery.DOC_VALUES_REWRITE + new Term(name(), indexedValueForSearch(value)), + syntaxFlags, + matchFlags, + RegexpQuery.DEFAULT_PROVIDER, + maxDeterminizedStates, + MultiTermQuery.DOC_VALUES_REWRITE ); break; } - return query; + return query; } @Override - public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, RewriteOverride rewriteOverride, QueryShardContext context) { + public Query rangeQuery( + Object lowerTerm, + Object upperTerm, + boolean includeLower, + boolean includeUpper, + RewriteOverride rewriteOverride, + QueryShardContext context + ) { if (context.allowExpensiveQueries() == false) { throw new OpenSearchException( "[range] queries on [text] or [keyword] fields cannot be executed when '" @@ -581,55 +583,53 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower case DEFAULT: if (isSearchable() && hasDocValues()) { Query indexQuery = new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper ); Query dvQuery = new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper, - MultiTermQuery.DOC_VALUES_REWRITE + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper, + MultiTermQuery.DOC_VALUES_REWRITE ); query = new IndexOrDocValuesQuery(indexQuery, dvQuery); - } - else if (hasDocValues()) { + } else if (hasDocValues()) { query = new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper, - MultiTermQuery.DOC_VALUES_REWRITE + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper, + MultiTermQuery.DOC_VALUES_REWRITE ); - } - else { + } else { query = super.rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context); } break; case INDEX_ONLY: failIfNotIndexed(); query = new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper ); break; case DOC_VALUES_ONLY: failIfNoDocValues(); query = new TermRangeQuery( - name(), - lowerTerm == null ? null : indexedValueForSearch(lowerTerm), - upperTerm == null ? null : indexedValueForSearch(upperTerm), - includeLower, - includeUpper, - MultiTermQuery.DOC_VALUES_REWRITE + name(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, + includeUpper, + MultiTermQuery.DOC_VALUES_REWRITE ); break; } @@ -671,8 +671,7 @@ public Query fuzzyQuery( context ); query = new IndexOrDocValuesQuery(indexQuery, dvQuery); - } - else if (hasDocValues()) { + } else if (hasDocValues()) { query = new FuzzyQuery( new Term(name(), indexedValueForSearch(value)), fuzziness.asDistance(BytesRefs.toString(value)), @@ -681,8 +680,7 @@ else if (hasDocValues()) { transpositions, MultiTermQuery.DOC_VALUES_REWRITE ); - } - else { + } else { query = super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); } break; @@ -702,7 +700,7 @@ else if (hasDocValues()) { ); break; } - return query; + return query; } @Override diff --git a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java index 1d26cc30270d6..dd32eb9a37392 100644 --- a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java @@ -295,30 +295,30 @@ public Query fuzzyQuery( } public Query fuzzyQuery( - Object value, - Fuzziness fuzziness, - int prefixLength, - int maxExpansions, - boolean transpositions, - @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, - QueryShardContext context + Object value, + Fuzziness fuzziness, + int prefixLength, + int maxExpansions, + boolean transpositions, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + QueryShardContext context ) { throw new IllegalArgumentException( - "Can only use fuzzy queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" + "Can only use fuzzy queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" ); } public Query prefixQuery( - String value, - @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, - boolean caseInsensitve, - QueryShardContext context + String value, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + boolean caseInsensitve, + QueryShardContext context ) { throw new QueryShardException( - context, - "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" + context, + "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" ); } @@ -356,16 +356,17 @@ public Query wildcardQuery( "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" ); } + public Query wildcardQuery( - String value, - @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, - boolean caseInsensitve, - QueryShardContext context + String value, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + boolean caseInsensitve, + QueryShardContext context ) { throw new QueryShardException( - context, - "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" + context, + "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" ); } @@ -392,17 +393,17 @@ public Query regexpQuery( } public Query regexpQuery( - String value, - int syntaxFlags, - int matchFlags, - int maxDeterminizedStates, - @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, - QueryShardContext context + String value, + int syntaxFlags, + int matchFlags, + int maxDeterminizedStates, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + QueryShardContext context ) { throw new QueryShardException( - context, - "Can only use regexp queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" + context, + "Can only use regexp queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" ); } diff --git a/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java index 16cde2b04612b..70c0da3e42dd6 100644 --- a/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java @@ -86,7 +86,14 @@ protected Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLo throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support range queries"); } - protected Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper,RewriteOverride rewriteOverride, QueryShardContext context) { + protected Query rangeQuery( + Object lowerTerm, + Object upperTerm, + boolean includeLower, + boolean includeUpper, + RewriteOverride rewriteOverride, + QueryShardContext context + ) { throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support range queries"); } diff --git a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java index 327dc655b0595..1cfc55045ed61 100644 --- a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java @@ -176,7 +176,6 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx String rewrite = null; String rewrite_override = null; - String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; boolean caseInsensitive = DEFAULT_CASE_INSENSITIVITY; @@ -204,7 +203,7 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx caseInsensitive = parser.booleanValue(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { rewrite_override = parser.textOrNull(); - }else { + } else { throw new ParsingException( parser.getTokenLocation(), "[prefix] query does not support [" + currentFieldName + "]" @@ -219,7 +218,11 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx } } - return new PrefixQueryBuilder(fieldName, value).rewrite(rewrite).boost(boost).queryName(queryName).caseInsensitive(caseInsensitive).rewrite_override(rewrite_override); + return new PrefixQueryBuilder(fieldName, value).rewrite(rewrite) + .boost(boost) + .queryName(queryName) + .caseInsensitive(caseInsensitive) + .rewrite_override(rewrite_override); } @Override @@ -273,7 +276,7 @@ protected boolean doEquals(PrefixQueryBuilder other) { return Objects.equals(fieldName, other.fieldName) && Objects.equals(value, other.value) && Objects.equals(rewrite, other.rewrite) - && Objects.equals(rewrite_override, other.rewrite_override) + && Objects.equals(rewrite_override, other.rewrite_override) && Objects.equals(caseInsensitive, other.caseInsensitive); } } diff --git a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java index 36a8f425a2ccd..f497f2f66a5ee 100644 --- a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java @@ -78,7 +78,6 @@ public class RangeQueryBuilder extends AbstractQueryBuilder i private static final ParseField RELATION_FIELD = new ParseField("relation"); private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); - private final String fieldName; private Object from; private Object to; @@ -381,7 +380,6 @@ public static RangeQueryBuilder fromXContent(XContentParser parser) throws IOExc String relation = null; String rewrite_override = null; - String currentFieldName = null; XContentParser.Token token; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { @@ -426,7 +424,7 @@ public static RangeQueryBuilder fromXContent(XContentParser parser) throws IOExc queryName = parser.text(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { rewrite_override = parser.textOrNull(); - }else { + } else { throw new ParsingException( parser.getTokenLocation(), "[range] query does not support [" + currentFieldName + "]" @@ -565,6 +563,6 @@ protected boolean doEquals(RangeQueryBuilder other) { && Objects.equals(includeLower, other.includeLower) && Objects.equals(includeUpper, other.includeUpper) && Objects.equals(format, other.format) - && Objects.equals(rewrite_override, other.rewrite_override); + && Objects.equals(rewrite_override, other.rewrite_override); } } diff --git a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java index cf65e44902677..cc339e7b3e312 100644 --- a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java @@ -271,7 +271,7 @@ public static RegexpQueryBuilder fromXContent(XContentParser parser) throws IOEx queryName = parser.text(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { rewrite_override = parser.textOrNull(); - }else { + } else { throw new ParsingException( parser.getTokenLocation(), "[regexp] query does not support [" + currentFieldName + "]" @@ -356,6 +356,7 @@ protected boolean doEquals(RegexpQueryBuilder other) { && Objects.equals(syntaxFlagsValue, other.syntaxFlagsValue) && Objects.equals(caseInsensitive, other.caseInsensitive) && Objects.equals(maxDeterminizedStates, other.maxDeterminizedStates) - && Objects.equals(rewrite, other.rewrite) && Objects.equals(rewrite_override, other.rewrite_override); + && Objects.equals(rewrite, other.rewrite) + && Objects.equals(rewrite_override, other.rewrite_override); } } diff --git a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java index 03007e68b138f..5b95483fbe0d9 100644 --- a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java @@ -217,9 +217,9 @@ public static WildcardQueryBuilder fromXContent(XContentParser parser) throws IO caseInsensitive = parser.booleanValue(); } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); - } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { + } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { rewrite_override = parser.textOrNull(); - }else { + } else { throw new ParsingException( parser.getTokenLocation(), "[wildcard] query does not support [" + currentFieldName + "]" @@ -237,7 +237,8 @@ public static WildcardQueryBuilder fromXContent(XContentParser parser) throws IO return new WildcardQueryBuilder(fieldName, value).rewrite(rewrite) .boost(boost) .queryName(queryName) - .caseInsensitive(caseInsensitive).rewrite_override(rewrite_override); + .caseInsensitive(caseInsensitive) + .rewrite_override(rewrite_override); } @Override @@ -288,6 +289,6 @@ protected boolean doEquals(WildcardQueryBuilder other) { && Objects.equals(value, other.value) && Objects.equals(rewrite, other.rewrite) && Objects.equals(caseInsensitive, other.caseInsensitive) - && Objects.equals(rewrite_override, other.rewrite_override); + && Objects.equals(rewrite_override, other.rewrite_override); } } diff --git a/server/src/main/java/org/opensearch/search/aggregations/bucket/BucketsAggregator.java b/server/src/main/java/org/opensearch/search/aggregations/bucket/BucketsAggregator.java index c85c61f6da29e..eef427754f535 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/bucket/BucketsAggregator.java +++ b/server/src/main/java/org/opensearch/search/aggregations/bucket/BucketsAggregator.java @@ -76,7 +76,7 @@ public abstract class BucketsAggregator extends AggregatorBase { public BucketsAggregator( String name, - AggregatorFactories factories, + AggregatorFactories factories, SearchContext context, Aggregator parent, CardinalityUpperBound bucketCardinality, From c3fb2152230371714e62f31c5f2519bdc314dff0 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Mon, 5 Aug 2024 16:53:46 -0700 Subject: [PATCH 09/23] Fix tests Signed-off-by: Harsha Vamsi Kalluri --- .../opensearch/index/mapper/KeywordFieldTypeTests.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java index 7426b65657860..c2c9b3942c163 100644 --- a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java +++ b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java @@ -136,20 +136,20 @@ public void testTermsQuery() { new TermInSetQuery("field", terms), new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, "field", terms) ); - assertEquals(expected, ft.termsQuery(Arrays.asList("foo", "bar"), null, RewriteOverride.DEFAULT)); + assertEquals(expected, ft.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null)); MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); Query expectedIndex = new TermInSetQuery("field", terms); - assertEquals(expectedIndex, onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), null, RewriteOverride.DEFAULT)); + assertEquals(expectedIndex, onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null)); MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); Query expectedDocValues = new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, "field", terms); - assertEquals(expectedDocValues, onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), null, RewriteOverride.DEFAULT)); + assertEquals(expectedDocValues, onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null)); MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"), null, RewriteOverride.DEFAULT) + () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"),RewriteOverride.DEFAULT,null) ); assertEquals( "Cannot search on field [field] since it is both not indexed, and does not have doc_values " + "enabled.", From de9e944ff715f23cb3f750c4f18988149a48216b Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Mon, 5 Aug 2024 16:54:42 -0700 Subject: [PATCH 10/23] Spotless Signed-off-by: Harsha Vamsi Kalluri --- .../java/org/opensearch/index/mapper/KeywordFieldTypeTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java index c2c9b3942c163..c3a1e7bbda64f 100644 --- a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java +++ b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java @@ -149,7 +149,7 @@ public void testTermsQuery() { MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"),RewriteOverride.DEFAULT,null) + () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null) ); assertEquals( "Cannot search on field [field] since it is both not indexed, and does not have doc_values " + "enabled.", From 6dc2b0b8937f32ca52ab421b6f7ad4da2f9e5116 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Thu, 8 Aug 2024 14:48:02 -0700 Subject: [PATCH 11/23] Add query overrides Signed-off-by: Harsha Vamsi Kalluri --- .../index/mapper/KeywordFieldMapper.java | 5 +- .../index/mapper/MappedFieldType.java | 39 ++-- .../index/query/FuzzyQueryBuilder.java | 47 ++++- .../index/query/PrefixQueryBuilder.java | 11 +- .../index/query/RangeQueryBuilder.java | 12 +- .../index/query/RegexpQueryBuilder.java | 18 +- .../index/query/TermsQueryBuilder.java | 16 +- .../index/query/WildcardQueryBuilder.java | 11 +- .../index/mapper/KeywordFieldTypeTests.java | 176 ++++++++++++++---- .../index/query/FuzzyQueryBuilderTests.java | 3 +- .../index/query/PrefixQueryBuilderTests.java | 2 +- .../index/query/RangeQueryBuilderTests.java | 1 + .../index/query/RegexpQueryBuilderTests.java | 1 + .../index/query/TermsQueryBuilderTests.java | 1 + .../query/WildcardQueryBuilderTests.java | 3 +- 15 files changed, 273 insertions(+), 73 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java index 01d33b7ddd9c2..f2d4e5c6943e3 100644 --- a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java +++ b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java @@ -730,8 +730,7 @@ public Query wildcardQuery( Query indexQuery = super.wildcardQuery(value, method, caseInsensitive, true, context); Query dvQuery = super.wildcardQuery(value, MultiTermQuery.DOC_VALUES_REWRITE, caseInsensitive, true, context); query = new IndexOrDocValuesQuery(indexQuery, dvQuery); - } - if (hasDocValues()) { + } else if (hasDocValues()) { Term term; value = normalizeWildcardPattern(name(), value, getTextSearchInfo().getSearchAnalyzer()); term = new Term(name(), value); @@ -739,6 +738,8 @@ public Query wildcardQuery( return AutomatonQueries.caseInsensitiveWildcardQuery(term, method); } query = new WildcardQuery(term, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.DOC_VALUES_REWRITE); + } else { + query = super.wildcardQuery(value, method, caseInsensitive, true, context); } break; case INDEX_ONLY: diff --git a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java index dd32eb9a37392..547c513ce3182 100644 --- a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java @@ -231,11 +231,7 @@ public Query termQueryCaseInsensitive(Object value, @Nullable QueryShardContext } public Query termsQuery(List values, @Nullable RewriteOverride rewriteOverride, @Nullable QueryShardContext context) { - BooleanQuery.Builder builder = new BooleanQuery.Builder(); - for (Object value : values) { - builder.add(termQuery(value, context), Occur.SHOULD); - } - return new ConstantScoreQuery(builder.build()); + return termsQuery(values, context); } /** Build a constant-scoring query that matches all values. The default implementation uses a @@ -266,6 +262,20 @@ public Query rangeQuery( throw new IllegalArgumentException("Field [" + name + "] of type [" + typeName() + "] does not support range queries"); } + public Query rangeQuery( + Object lowerTerm, + Object upperTerm, + boolean includeLower, + boolean includeUpper, + ShapeRelation relation, + ZoneId timeZone, + DateMathParser parser, + @Nullable RewriteOverride rewriteOverride, + QueryShardContext context + ) { + return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, relation, timeZone, parser, context); + } + public Query fuzzyQuery( Object value, Fuzziness fuzziness, @@ -304,9 +314,7 @@ public Query fuzzyQuery( @Nullable RewriteOverride rewriteOverride, QueryShardContext context ) { - throw new IllegalArgumentException( - "Can only use fuzzy queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" - ); + return fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); } public Query prefixQuery( @@ -316,10 +324,7 @@ public Query prefixQuery( boolean caseInsensitve, QueryShardContext context ) { - throw new QueryShardException( - context, - "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" - ); + return prefixQuery(value, method, caseInsensitve, context); } // Case sensitive form of prefix query @@ -364,10 +369,7 @@ public Query wildcardQuery( boolean caseInsensitve, QueryShardContext context ) { - throw new QueryShardException( - context, - "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" - ); + return wildcardQuery(value, method, caseInsensitve, context); } /** always normalizes the wildcard pattern to lowercase */ @@ -401,10 +403,7 @@ public Query regexpQuery( @Nullable RewriteOverride rewriteOverride, QueryShardContext context ) { - throw new QueryShardException( - context, - "Can only use regexp queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]" - ); + return regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); } public Query existsQuery(QueryShardContext context) { diff --git a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java index 93c32bbedcef4..acf3fac459267 100644 --- a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java @@ -35,6 +35,7 @@ import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.Query; +import org.opensearch.Version; import org.opensearch.common.unit.Fuzziness; import org.opensearch.common.xcontent.LoggingDeprecationHandler; import org.opensearch.core.ParseField; @@ -45,6 +46,7 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.mapper.MappedFieldType; +import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -78,6 +80,10 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder i private static final ParseField TRANSPOSITIONS_FIELD = new ParseField("transpositions"); private static final ParseField REWRITE_FIELD = new ParseField("rewrite"); + private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); + + private String rewrite_override; + private final String fieldName; private final Object value; @@ -181,6 +187,9 @@ public FuzzyQueryBuilder(StreamInput in) throws IOException { maxExpansions = in.readVInt(); transpositions = in.readBoolean(); rewrite = in.readOptionalString(); + if (in.getVersion().after(Version.V_2_16_0)) { + rewrite_override = in.readOptionalString(); + } } @Override @@ -192,6 +201,9 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeVInt(this.maxExpansions); out.writeBoolean(this.transpositions); out.writeOptionalString(this.rewrite); + if (out.getVersion().after(Version.V_2_16_0)) { + out.writeOptionalString(rewrite_override); + } } @Override @@ -248,6 +260,11 @@ public String rewrite() { return this.rewrite; } + private FuzzyQueryBuilder rewrite_override(String rewrite_override) { + this.rewrite_override = rewrite_override; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(NAME); @@ -261,6 +278,9 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep builder.field(REWRITE_FIELD.getPreferredName(), rewrite); } printBoostAndQueryName(builder); + if (rewrite_override != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + } builder.endObject(); builder.endObject(); } @@ -273,6 +293,7 @@ public static FuzzyQueryBuilder fromXContent(XContentParser parser) throws IOExc int maxExpansions = FuzzyQueryBuilder.DEFAULT_MAX_EXPANSIONS; boolean transpositions = FuzzyQueryBuilder.DEFAULT_TRANSPOSITIONS; String rewrite = null; + String rewrite_override = null; String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; String currentFieldName = null; @@ -303,6 +324,8 @@ public static FuzzyQueryBuilder fromXContent(XContentParser parser) throws IOExc transpositions = parser.booleanValue(); } else if (REWRITE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { rewrite = parser.textOrNull(); + } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { + rewrite_override = parser.textOrNull(); } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); } else { @@ -330,7 +353,8 @@ public static FuzzyQueryBuilder fromXContent(XContentParser parser) throws IOExc .transpositions(transpositions) .rewrite(rewrite) .boost(boost) - .queryName(queryName); + .queryName(queryName) + .rewrite_override(rewrite_override); } @Override @@ -360,14 +384,28 @@ protected Query doToQuery(QueryShardContext context) throws IOException { Query query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, null, context); if (query instanceof MultiTermQuery) { MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE); - QueryParsers.setRewriteMethod((MultiTermQuery) query, rewriteMethod); + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + query = fieldType.fuzzyQuery( + value, + fuzziness, + prefixLength, + maxExpansions, + transpositions, + rewriteMethod, + rewriteOverride, + context + ); } return query; } @Override protected int doHashCode() { - return Objects.hash(fieldName, value, fuzziness, prefixLength, maxExpansions, transpositions, rewrite); + return Objects.hash(fieldName, value, fuzziness, prefixLength, maxExpansions, transpositions, rewrite, rewrite_override); } @Override @@ -378,6 +416,7 @@ protected boolean doEquals(FuzzyQueryBuilder other) { && Objects.equals(prefixLength, other.prefixLength) && Objects.equals(maxExpansions, other.maxExpansions) && Objects.equals(transpositions, other.transpositions) - && Objects.equals(rewrite, other.rewrite); + && Objects.equals(rewrite, other.rewrite) + && Objects.equals(rewrite_override, other.rewrite_override); } } diff --git a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java index 1cfc55045ed61..b40b0250f4029 100644 --- a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java @@ -47,6 +47,7 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; +import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -162,10 +163,10 @@ public void doXContent(XContentBuilder builder, Params params) throws IOExceptio if (caseInsensitive != DEFAULT_CASE_INSENSITIVITY) { builder.field(CASE_INSENSITIVE_FIELD.getPreferredName(), caseInsensitive); } + printBoostAndQueryName(builder); if (rewrite_override != null) { builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); } - printBoostAndQueryName(builder); builder.endObject(); builder.endObject(); } @@ -241,7 +242,13 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws // This logic is correct for all field types, but by only applying it to constant // fields we also have the guarantee that it doesn't perform I/O, which is important // since rewrites might happen on a network thread. - Query query = fieldType.prefixQuery(value, null, caseInsensitive, context); // the rewrite method doesn't matter + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + Query query = fieldType.prefixQuery(value, null, rewriteOverride, caseInsensitive, context); // the rewrite method doesn't + // matter if (query instanceof MatchAllDocsQuery) { return new MatchAllQueryBuilder(); } else if (query instanceof MatchNoDocsQuery) { diff --git a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java index f497f2f66a5ee..4922c65ee624f 100644 --- a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java @@ -39,6 +39,7 @@ import org.opensearch.common.geo.ShapeRelation; import org.opensearch.common.time.DateFormatter; import org.opensearch.common.time.DateMathParser; +import org.opensearch.common.xcontent.LoggingDeprecationHandler; import org.opensearch.core.ParseField; import org.opensearch.core.common.ParsingException; import org.opensearch.core.common.Strings; @@ -48,6 +49,8 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.mapper.FieldNamesFieldMapper; import org.opensearch.index.mapper.MappedFieldType; +import org.opensearch.index.mapper.RewriteOverride; +import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; import java.time.DateTimeException; @@ -359,10 +362,10 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep if (relation != null) { builder.field(RELATION_FIELD.getPreferredName(), relation.getRelationName()); } + printBoostAndQueryName(builder); if (rewrite_override != null) { builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); } - printBoostAndQueryName(builder); builder.endObject(); builder.endObject(); } @@ -546,7 +549,12 @@ protected Query doToQuery(QueryShardContext context) throws IOException { throw new IllegalStateException("Rewrite first"); } DateMathParser forcedDateParser = getForceDateParser(); - return mapper.rangeQuery(from, to, includeLower, includeUpper, relation, timeZone, forcedDateParser, context); + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + return mapper.rangeQuery(from, to, includeLower, includeUpper, relation, timeZone, forcedDateParser, rewriteOverride, context); } @Override diff --git a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java index cc339e7b3e312..0c68c7b57fcf9 100644 --- a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java @@ -50,6 +50,7 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.IndexSettings; import org.opensearch.index.mapper.MappedFieldType; +import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -222,10 +223,10 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep if (rewrite != null) { builder.field(REWRITE_FIELD.getPreferredName(), rewrite); } + printBoostAndQueryName(builder); if (rewrite_override != null) { builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); } - printBoostAndQueryName(builder); builder.endObject(); builder.endObject(); } @@ -326,7 +327,20 @@ protected Query doToQuery(QueryShardContext context) throws QueryShardException, MappedFieldType fieldType = context.fieldMapper(fieldName); if (fieldType != null) { - query = fieldType.regexpQuery(value, sanitisedSyntaxFlag, matchFlagsValue, maxDeterminizedStates, method, context); + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + query = fieldType.regexpQuery( + value, + sanitisedSyntaxFlag, + matchFlagsValue, + maxDeterminizedStates, + method, + rewriteOverride, + context + ); } if (query == null) { if (method == null) { diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index 8c03e67700a0f..31f9e85500c50 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -42,6 +42,7 @@ import org.opensearch.client.Client; import org.opensearch.common.SetOnce; import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.common.xcontent.LoggingDeprecationHandler; import org.opensearch.common.xcontent.support.XContentMapValues; import org.opensearch.core.ParseField; import org.opensearch.core.action.ActionListener; @@ -55,6 +56,8 @@ import org.opensearch.index.IndexSettings; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; +import org.opensearch.index.mapper.RewriteOverride; +import org.opensearch.index.query.support.QueryParsers; import org.opensearch.indices.TermsLookup; import java.io.IOException; @@ -379,9 +382,6 @@ public Object get(int index) { @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(NAME); - if (rewrite_override != null) { - builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); - } if (this.termsLookup != null) { builder.startObject(fieldName); termsLookup.toXContent(builder, params); @@ -390,6 +390,9 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep builder.field(fieldName, convertBack(values)); } printBoostAndQueryName(builder); + if (rewrite_override != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + } builder.endObject(); } @@ -507,7 +510,12 @@ protected Query doToQuery(QueryShardContext context) throws IOException { if (fieldType == null) { throw new IllegalStateException("Rewrite first"); } - return fieldType.termsQuery(values, context); + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + return fieldType.termsQuery(values, rewriteOverride, context); } private void fetch(TermsLookup termsLookup, Client client, ActionListener> actionListener) { diff --git a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java index 5b95483fbe0d9..3916eeb41e426 100644 --- a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java @@ -47,6 +47,7 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; +import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -177,10 +178,10 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep if (caseInsensitive != DEFAULT_CASE_INSENSITIVITY) { builder.field(CASE_INSENSITIVE_FIELD.getPreferredName(), caseInsensitive); } + printBoostAndQueryName(builder); if (rewrite_override != null) { builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); } - printBoostAndQueryName(builder); builder.endObject(); builder.endObject(); } @@ -252,7 +253,13 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws // This logic is correct for all field types, but by only applying it to constant // fields we also have the guarantee that it doesn't perform I/O, which is important // since rewrites might happen on a network thread. - Query query = fieldType.wildcardQuery(value, null, caseInsensitive, context); // the rewrite method doesn't matter + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + Query query = fieldType.wildcardQuery(value, null, rewriteOverride, caseInsensitive, context); // the rewrite method doesn't + // matter if (query instanceof MatchAllDocsQuery) { return new MatchAllQueryBuilder(); } else if (query instanceof MatchNoDocsQuery) { diff --git a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java index c3a1e7bbda64f..89cc4326eafbe 100644 --- a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java +++ b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java @@ -141,10 +141,12 @@ public void testTermsQuery() { MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); Query expectedIndex = new TermInSetQuery("field", terms); assertEquals(expectedIndex, onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null)); + assertEquals(expectedIndex, onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.INDEX_ONLY, null)); MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); Query expectedDocValues = new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, "field", terms); assertEquals(expectedDocValues, onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null)); + assertEquals(expectedDocValues, onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DOC_VALUES_ONLY, null)); MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( @@ -175,7 +177,7 @@ public void testExistsQuery() { } public void testRangeQuery() { - MappedFieldType ft = new KeywordFieldType("field"); + KeywordFieldType ft = new KeywordFieldType("field"); Query indexExpected = new TermRangeQuery("field", BytesRefs.toBytesRef("foo"), BytesRefs.toBytesRef("bar"), true, false); Query dvExpected = new TermRangeQuery( @@ -188,19 +190,21 @@ public void testRangeQuery() { ); Query expected = new IndexOrDocValuesQuery(indexExpected, dvExpected); - Query actual = ft.rangeQuery("foo", "bar", true, false, null, null, null, MOCK_QSC); + Query actual = ft.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC); assertEquals(expected, actual); - MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); - assertEquals(indexExpected, onlyIndexed.rangeQuery("foo", "bar", true, false, null, null, null, MOCK_QSC)); + KeywordFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); + assertEquals(indexExpected, onlyIndexed.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC)); + assertEquals(indexExpected, onlyIndexed.rangeQuery("foo", "bar", true, false, RewriteOverride.INDEX_ONLY, MOCK_QSC)); - MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); - assertEquals(dvExpected, onlyDocValues.rangeQuery("foo", "bar", true, false, null, null, null, MOCK_QSC)); + KeywordFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); + assertEquals(dvExpected, onlyDocValues.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC)); + assertEquals(dvExpected, onlyDocValues.rangeQuery("foo", "bar", true, false, RewriteOverride.DOC_VALUES_ONLY, MOCK_QSC)); - MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); + KeywordFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.rangeQuery("foo", "bar", true, false, null, null, null, MOCK_QSC) + () -> unsearchable.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC) ); assertEquals( @@ -210,7 +214,7 @@ public void testRangeQuery() { OpenSearchException ee = expectThrows( OpenSearchException.class, - () -> ft.rangeQuery("foo", "bar", true, false, null, null, null, MOCK_QSC_DISALLOW_EXPENSIVE) + () -> ft.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC_DISALLOW_EXPENSIVE) ); assertEquals( "[range] queries on [text] or [keyword] fields cannot be executed when " + "'search.allow_expensive_queries' is set to false.", @@ -225,12 +229,19 @@ public void testRegexpQuery() { new RegexpQuery(new Term("field", "foo.*")), new RegexpQuery(new Term("field", "foo.*"), 0, 0, RegexpQuery.DEFAULT_PROVIDER, 10, MultiTermQuery.DOC_VALUES_REWRITE) ), - ft.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, MOCK_QSC) + ft.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.DEFAULT, MOCK_QSC) ); Query indexExpected = new RegexpQuery(new Term("field", "foo.*")); MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); - assertEquals(indexExpected, onlyIndexed.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, MOCK_QSC)); + assertEquals( + indexExpected, + onlyIndexed.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.DEFAULT, MOCK_QSC) + ); + assertEquals( + indexExpected, + onlyIndexed.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.INDEX_ONLY, MOCK_QSC) + ); Query dvExpected = new RegexpQuery( new Term("field", "foo.*"), @@ -241,12 +252,19 @@ public void testRegexpQuery() { MultiTermQuery.DOC_VALUES_REWRITE ); MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); - assertEquals(dvExpected, onlyDocValues.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.DOC_VALUES_REWRITE, MOCK_QSC)); + assertEquals( + dvExpected, + onlyDocValues.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.DOC_VALUES_REWRITE, RewriteOverride.DEFAULT, MOCK_QSC) + ); + assertEquals( + dvExpected, + onlyDocValues.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.DOC_VALUES_REWRITE, RewriteOverride.DOC_VALUES_ONLY, MOCK_QSC) + ); MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.regexpQuery("foo.*", 0, 0, 10, null, MOCK_QSC) + () -> unsearchable.regexpQuery("foo.*", 0, 0, 10, null, RewriteOverride.DEFAULT, MOCK_QSC) ); assertEquals( "Cannot search on field [field] since it is both not indexed, and does not have doc_values " + "enabled.", @@ -255,36 +273,92 @@ public void testRegexpQuery() { OpenSearchException ee = expectThrows( OpenSearchException.class, - () -> ft.regexpQuery("foo.*", randomInt(10), 0, randomInt(10) + 1, null, MOCK_QSC_DISALLOW_EXPENSIVE) + () -> ft.regexpQuery("foo.*", randomInt(10), 0, randomInt(10) + 1, null, RewriteOverride.DEFAULT, MOCK_QSC_DISALLOW_EXPENSIVE) ); assertEquals("[regexp] queries cannot be executed when 'search.allow_expensive_queries' is set to false.", ee.getMessage()); } public void testFuzzyQuery() { - MappedFieldType ft = new KeywordFieldType("field"); + KeywordFieldType ft = new KeywordFieldType("field"); assertEquals( new IndexOrDocValuesQuery( new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true), new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true, MultiTermQuery.DOC_VALUES_REWRITE) ), - ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, null, MOCK_QSC) + ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, null, RewriteOverride.DEFAULT, MOCK_QSC) ); Query indexExpected = new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true); - MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); - assertEquals(indexExpected, onlyIndexed.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, MOCK_QSC)); + KeywordFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); + assertEquals( + indexExpected, + onlyIndexed.fuzzyQuery( + "foo", + Fuzziness.fromEdits(2), + 1, + 50, + true, + FuzzyQuery.defaultRewriteMethod(50), + RewriteOverride.DEFAULT, + MOCK_QSC + ) + ); + assertEquals( + indexExpected, + onlyIndexed.fuzzyQuery( + "foo", + Fuzziness.fromEdits(2), + 1, + 50, + true, + FuzzyQuery.defaultRewriteMethod(50), + RewriteOverride.INDEX_ONLY, + MOCK_QSC + ) + ); Query dvExpected = new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true, MultiTermQuery.DOC_VALUES_REWRITE); - MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); + KeywordFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); assertEquals( dvExpected, - onlyDocValues.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, MultiTermQuery.DOC_VALUES_REWRITE, MOCK_QSC) + onlyDocValues.fuzzyQuery( + "foo", + Fuzziness.fromEdits(2), + 1, + 50, + true, + MultiTermQuery.DOC_VALUES_REWRITE, + RewriteOverride.DEFAULT, + MOCK_QSC + ) + ); + assertEquals( + dvExpected, + onlyDocValues.fuzzyQuery( + "foo", + Fuzziness.fromEdits(2), + 1, + 50, + true, + MultiTermQuery.DOC_VALUES_REWRITE, + RewriteOverride.DOC_VALUES_ONLY, + MOCK_QSC + ) ); - MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); + KeywordFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, MultiTermQuery.DOC_VALUES_REWRITE, MOCK_QSC) + () -> unsearchable.fuzzyQuery( + "foo", + Fuzziness.fromEdits(2), + 1, + 50, + true, + MultiTermQuery.DOC_VALUES_REWRITE, + RewriteOverride.DEFAULT, + MOCK_QSC + ) ); assertEquals( "Cannot search on field [field] since it is both not indexed, and does not have doc_values " + "enabled.", @@ -293,13 +367,22 @@ public void testFuzzyQuery() { OpenSearchException ee = expectThrows( OpenSearchException.class, - () -> ft.fuzzyQuery("foo", Fuzziness.AUTO, randomInt(10) + 1, randomInt(10) + 1, randomBoolean(), MOCK_QSC_DISALLOW_EXPENSIVE) + () -> ft.fuzzyQuery( + "foo", + Fuzziness.AUTO, + randomInt(10) + 1, + randomInt(10) + 1, + randomBoolean(), + FuzzyQuery.defaultRewriteMethod(randomInt(10) + 1), + RewriteOverride.DEFAULT, + MOCK_QSC_DISALLOW_EXPENSIVE + ) ); assertEquals("[fuzzy] queries cannot be executed when 'search.allow_expensive_queries' is set to false.", ee.getMessage()); } public void testWildCardQuery() { - MappedFieldType ft = new KeywordFieldType("field"); + KeywordFieldType ft = new KeywordFieldType("field"); Query expected = new IndexOrDocValuesQuery( new WildcardQuery(new Term("field", new BytesRef("foo*"))), new WildcardQuery( @@ -308,24 +391,47 @@ public void testWildCardQuery() { MultiTermQuery.DOC_VALUES_REWRITE ) ); - assertEquals(expected, ft.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, MOCK_QSC)); + assertEquals( + expected, + ft.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.DEFAULT, false, MOCK_QSC) + ); Query indexExpected = new WildcardQuery(new Term("field", new BytesRef("foo*"))); - MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); - assertEquals(indexExpected, onlyIndexed.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, MOCK_QSC)); + KeywordFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); + assertEquals( + indexExpected, + onlyIndexed.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.DEFAULT, false, MOCK_QSC) + ); + assertEquals( + indexExpected, + onlyIndexed.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.INDEX_ONLY, false, MOCK_QSC) + ); Query dvExpected = new WildcardQuery( new Term("field", new BytesRef("foo*")), Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.DOC_VALUES_REWRITE ); - MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); - assertEquals(dvExpected, onlyDocValues.wildcardQuery("foo*", MultiTermQuery.DOC_VALUES_REWRITE, MOCK_QSC)); + KeywordFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); + assertEquals( + dvExpected, + onlyDocValues.wildcardQuery("foo*", MultiTermQuery.DOC_VALUES_REWRITE, RewriteOverride.DEFAULT, false, MOCK_QSC) + ); + assertEquals( + dvExpected, + onlyDocValues.wildcardQuery("foo*", MultiTermQuery.DOC_VALUES_REWRITE, RewriteOverride.DOC_VALUES_ONLY, false, MOCK_QSC) + ); - MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); + KeywordFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, MOCK_QSC) + () -> unsearchable.wildcardQuery( + "foo*", + MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, + RewriteOverride.DEFAULT, + false, + MOCK_QSC + ) ); assertEquals( "Cannot search on field [field] since it is both not indexed, and does not have doc_values " + "enabled.", @@ -334,7 +440,13 @@ public void testWildCardQuery() { OpenSearchException ee = expectThrows( OpenSearchException.class, - () -> ft.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, MOCK_QSC_DISALLOW_EXPENSIVE) + () -> ft.wildcardQuery( + "foo*", + MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, + RewriteOverride.DEFAULT, + false, + MOCK_QSC_DISALLOW_EXPENSIVE + ) ); assertEquals("[wildcard] queries cannot be executed when 'search.allow_expensive_queries' is set to false.", ee.getMessage()); } diff --git a/server/src/test/java/org/opensearch/index/query/FuzzyQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/FuzzyQueryBuilderTests.java index 42c905301c390..02f42aed8bb24 100644 --- a/server/src/test/java/org/opensearch/index/query/FuzzyQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/FuzzyQueryBuilderTests.java @@ -266,7 +266,8 @@ public void testFromJson() throws IOException { + " \"prefix_length\" : 0,\n" + " \"max_expansions\" : 100,\n" + " \"transpositions\" : false,\n" - + " \"boost\" : 42.0\n" + + " \"boost\" : 42.0,\n" + + " \"rewrite_override\" : \"index_only\"\n" + " }\n" + " }\n" + "}"; diff --git a/server/src/test/java/org/opensearch/index/query/PrefixQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/PrefixQueryBuilderTests.java index 52093e65d0122..56ab0c1b38c0b 100644 --- a/server/src/test/java/org/opensearch/index/query/PrefixQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/PrefixQueryBuilderTests.java @@ -115,7 +115,7 @@ public void testBlendedRewriteMethod() throws IOException { } public void testFromJson() throws IOException { - String json = "{ \"prefix\" : { \"user\" : { \"value\" : \"ki\", \"boost\" : 2.0" + "} }}"; + String json = "{ \"prefix\" : { \"user\" : { \"value\" : \"ki\", \"boost\" : 2.0 , \"rewrite_override\":\"index_only\"}}}"; PrefixQueryBuilder parsed = (PrefixQueryBuilder) parseQuery(json); checkGeneratedJson(json, parsed); diff --git a/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java index e72be29b85b63..86f645957b78b 100644 --- a/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java @@ -421,6 +421,7 @@ public void testFromJson() throws IOException { + " \"include_upper\" : true,\n" + " \"time_zone\" : \"+01:00\",\n" + " \"boost\" : 1.0\n" + + " \"rewrite_override\" : \"index_only\"\n" + " }\n" + " }\n" + "}"; diff --git a/server/src/test/java/org/opensearch/index/query/RegexpQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/RegexpQueryBuilderTests.java index 30c8c07fa2c27..80c87b5e85e30 100644 --- a/server/src/test/java/org/opensearch/index/query/RegexpQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/RegexpQueryBuilderTests.java @@ -123,6 +123,7 @@ public void testFromJson() throws IOException { + " \"case_insensitive\" : true,\n" + " \"max_determinized_states\" : 20000,\n" + " \"boost\" : 1.0\n" + + " \"rewrite_override\" : \"index_only\"\n" + " }\n" + " }\n" + "}"; diff --git a/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java index 1b74b02c16994..9bed164fb2b3a 100644 --- a/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java @@ -294,6 +294,7 @@ public void testFromJson() throws IOException { + " \"terms\" : {\n" + " \"user\" : [ \"foobar\", \"opensearch\" ],\n" + " \"boost\" : 1.0\n" + + " \"rewrite_override\": \"index_only\"\n" + " }\n" + "}"; diff --git a/server/src/test/java/org/opensearch/index/query/WildcardQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/WildcardQueryBuilderTests.java index f4ec241a64a26..0ff60dd3a3e6a 100644 --- a/server/src/test/java/org/opensearch/index/query/WildcardQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/WildcardQueryBuilderTests.java @@ -118,7 +118,8 @@ public void testEmptyValue() throws IOException { } public void testFromJson() throws IOException { - String json = "{ \"wildcard\" : { \"user\" : { \"wildcard\" : \"ki*y\", \"boost\" : 2.0" + " } }}"; + String json = + "{ \"wildcard\" : { \"user\" : { \"wildcard\" : \"ki*y\", \"boost\" : 2.0, \"rewrite_override\" : \"index_only\"} }}"; WildcardQueryBuilder parsed = (WildcardQueryBuilder) parseQuery(json); checkGeneratedJson(json, parsed); assertEquals(json, "ki*y", parsed.value()); From 6b0921a01c5d0984ca44f5734aa842dc413ff5ec Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Fri, 9 Aug 2024 13:15:22 -0700 Subject: [PATCH 12/23] Adding yaml tests Signed-off-by: Harsha Vamsi Kalluri --- .../test/search/340_doc_values_field.yml | 486 ++++++++++++++++++ .../index/mapper/SimpleMappedFieldType.java | 24 +- .../index/mapper/StringFieldType.java | 40 +- .../index/query/FuzzyQueryBuilder.java | 12 +- .../index/query/PrefixQueryBuilder.java | 7 +- .../index/query/WildcardQueryBuilder.java | 7 +- .../index/query/RangeQueryBuilderTests.java | 2 +- .../index/query/RegexpQueryBuilderTests.java | 2 +- 8 files changed, 568 insertions(+), 12 deletions(-) diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml index a133060f07c6f..c23584102b212 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml @@ -71,6 +71,166 @@ - '{ "index": { "_index": "test-iodvq", "_id": "3" } }' - '{ "some_keyword": "5", "byte": 122, "double": 102.0, "float": "802.0", "half_float": "402.0", "integer": 1292, "long": 13458, "short": 152, "unsigned_long": 10223372036854775802, "ip_field": "192.168.0.3", "boolean": false, "date_nanos": "2024-10-29T12:12:12.987654321Z", "date": "2024-10-29T12:12:12.987Z" }' + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + terms: + some_keyword: ["400", "5"] + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + terms: { + some_keyword: ["400", "5"], + rewrite_override: "index_only" + } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + terms: { + some_keyword: ["400", "5"], + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + fuzzy: + some_keyword: { + value: "402" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + fuzzy: + some_keyword: { + value: "402", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + fuzzy: + some_keyword: { + value: "402", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + regexp: + some_keyword: { + value: "40*" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + regexp: + some_keyword: { + value: "40*", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + regexp: + some_keyword: { + value: "40*", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + wildcard: + some_keyword: { + value: "ing*" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + wildcard: + some_keyword: { + value: "ing*", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + wildcard: + some_keyword: { + value: "ing*", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + - do: search: rest_total_hits_as_int: true @@ -82,6 +242,34 @@ - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + prefix: + some_keyword: { + value: "ing", + rewrite_override: "index_only" + } + + - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + prefix: + some_keyword: { + value: "ing", + rewrite_override: "doc_values_only" + } + + - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + - do: search: rest_total_hits_as_int: true @@ -95,6 +283,36 @@ - match: { hits.total: 2 } + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + range: { + "some_keyword": { + "lt": 500, + rewrite_override: "index_only" + + } } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-iodvq + body: + query: + range: { + "some_keyword": { + "lt": 500, + rewrite_override: "doc_values_only" + + } } + + - match: { hits.total: 2 } + - do: search: @@ -608,6 +826,111 @@ - '{ "index": { "_index": "test-index", "_id": "3" } }' - '{ "some_keyword": "5", "byte": 122, "double": 102.0, "float": "802.0", "half_float": "402.0", "integer": 1292, "long": 13458, "short": 152, "unsigned_long": 10223372036854775802, "ip_field": "192.168.0.3", "boolean": false, "date_nanos": "2024-10-29T12:12:12.123456789Z", "date": "2024-10-29T12:12:12.987Z" }' + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + terms: + some_keyword: ["400", "5"] + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + terms: { + some_keyword: ["400", "5"], + rewrite_override: "index_only" + } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + fuzzy: + some_keyword: { + value: "402" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + fuzzy: + some_keyword: { + value: "402", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + regexp: + some_keyword: { + value: "40*" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + regexp: + some_keyword: { + value: "40*", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + wildcard: + some_keyword: { + value: "ing*" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + wildcard: + some_keyword: { + value: "ing*", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + - do: search: rest_total_hits_as_int: true @@ -619,6 +942,20 @@ - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + prefix: + some_keyword: { + value: "ing", + rewrite_override: "index_only" + } + + - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + - do: search: rest_total_hits_as_int: true @@ -632,6 +969,21 @@ - match: { hits.total: 2 } + - do: + search: + rest_total_hits_as_int: true + index: test-index + body: + query: + range: { + "some_keyword": { + "lt": 500, + rewrite_override: "index_only" + + } } + + - match: { hits.total: 2 } + - do: search: rest_total_hits_as_int: true @@ -1150,6 +1502,111 @@ - '{ "index": { "_index": "test-doc-values", "_id": "3" } }' - '{ "some_keyword": "5", "byte": 122, "double": 102.0, "float": "802.0", "half_float": "402.0", "integer": 1292, "long": 13458, "short": 152, "unsigned_long": 10223372036854775802, "ip_field": "192.168.0.3", "boolean": false, "date_nanos": "2024-10-29T12:12:12.123456789Z", "date": "2024-10-29T12:12:12.987Z" }' + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + terms: + some_keyword: ["400", "5"] + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + terms: { + some_keyword: ["400", "5"], + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + fuzzy: + some_keyword: { + value: "402" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + fuzzy: + some_keyword: { + value: "402", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + regexp: + some_keyword: { + value: "40*" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + regexp: + some_keyword: { + value: "40*", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + wildcard: + some_keyword: { + value: "ing*" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + wildcard: + some_keyword: { + value: "ing*", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + - do: search: rest_total_hits_as_int: true @@ -1161,6 +1618,20 @@ - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + prefix: + some_keyword: { + value: "ing", + rewrite_override: "doc_values_only" + } + + - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + - do: search: rest_total_hits_as_int: true @@ -1174,6 +1645,21 @@ - match: { hits.total: 2 } + - do: + search: + rest_total_hits_as_int: true + index: test-doc-values + body: + query: + range: { + "some_keyword": { + "lt": 500, + rewrite_override: "doc_values_only" + + } } + + - match: { hits.total: 2 } + - do: search: rest_total_hits_as_int: true diff --git a/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java index 70c0da3e42dd6..3616458e8d123 100644 --- a/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java @@ -33,6 +33,7 @@ package org.opensearch.index.mapper; import org.apache.lucene.search.Query; +import org.opensearch.common.Nullable; import org.opensearch.common.geo.ShapeRelation; import org.opensearch.common.time.DateMathParser; import org.opensearch.index.query.QueryShardContext; @@ -78,6 +79,27 @@ public final Query rangeQuery( return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context); } + @Override + public final Query rangeQuery( + Object lowerTerm, + Object upperTerm, + boolean includeLower, + boolean includeUpper, + ShapeRelation relation, + ZoneId timeZone, + DateMathParser parser, + @Nullable RewriteOverride rewriteOverride, + QueryShardContext context + ) { + if (relation == ShapeRelation.DISJOINT) { + throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support DISJOINT ranges"); + } + // We do not fail on non-null time zones and date parsers + // The reasoning is that on query parsers, you might want to set a time zone or format for date fields + // but then the API has no way to know which fields are dates and which fields are not dates + return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, rewriteOverride, context); + } + /** * Same as {@link #rangeQuery(Object, Object, boolean, boolean, ShapeRelation, ZoneId, DateMathParser, QueryShardContext)} * but without the trouble of relations or date-specific options. @@ -94,7 +116,7 @@ protected Query rangeQuery( RewriteOverride rewriteOverride, QueryShardContext context ) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support range queries"); + return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context); } } diff --git a/server/src/main/java/org/opensearch/index/mapper/StringFieldType.java b/server/src/main/java/org/opensearch/index/mapper/StringFieldType.java index 682ccc13f769d..08831b3d151f5 100644 --- a/server/src/main/java/org/opensearch/index/mapper/StringFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/StringFieldType.java @@ -45,6 +45,7 @@ import org.apache.lucene.util.BytesRefBuilder; import org.apache.lucene.util.automaton.Operations; import org.opensearch.OpenSearchException; +import org.opensearch.common.Nullable; import org.opensearch.common.lucene.BytesRefs; import org.opensearch.common.lucene.search.AutomatonQueries; import org.opensearch.common.unit.Fuzziness; @@ -110,7 +111,7 @@ public Query fuzzyQuery( int prefixLength, int maxExpansions, boolean transpositions, - MultiTermQuery.RewriteMethod method, + @Nullable MultiTermQuery.RewriteMethod method, QueryShardContext context ) { if (!context.allowExpensiveQueries()) { @@ -132,6 +133,20 @@ public Query fuzzyQuery( ); } + @Override + public Query fuzzyQuery( + Object value, + Fuzziness fuzziness, + int prefixLength, + int maxExpansions, + boolean transpositions, + @Nullable MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + QueryShardContext context + ) { + return fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); + } + @Override public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, boolean caseInsensitive, QueryShardContext context) { if (context.allowExpensiveQueries() == false) { @@ -188,6 +203,17 @@ public Query wildcardQuery(String value, MultiTermQuery.RewriteMethod method, bo return wildcardQuery(value, method, caseInsensitive, false, context); } + @Override + public Query wildcardQuery( + String value, + MultiTermQuery.RewriteMethod method, + @Nullable RewriteOverride rewriteOverride, + boolean caseInsensitive, + QueryShardContext context + ) { + return wildcardQuery(value, method, caseInsensitive, context); + } + /** always normalizes the wildcard pattern to lowercase */ @Override public Query normalizedWildcardQuery(String value, MultiTermQuery.RewriteMethod method, QueryShardContext context) { @@ -279,4 +305,16 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower includeUpper ); } + + @Override + public Query rangeQuery( + Object lowerTerm, + Object upperTerm, + boolean includeLower, + boolean includeUpper, + @Nullable RewriteOverride rewriteOverride, + QueryShardContext context + ) { + return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context); + } } diff --git a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java index acf3fac459267..cf774fef0e88c 100644 --- a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java @@ -381,14 +381,14 @@ protected Query doToQuery(QueryShardContext context) throws IOException { throw new IllegalStateException("Rewrite first"); } String rewrite = this.rewrite; - Query query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, null, context); + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + Query query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, null, rewriteOverride, context); if (query instanceof MultiTermQuery) { MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE); - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( - rewrite_override, - RewriteOverride.DEFAULT, - LoggingDeprecationHandler.INSTANCE - ); query = fieldType.fuzzyQuery( value, fuzziness, diff --git a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java index b40b0250f4029..2e6212f5b0948 100644 --- a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java @@ -270,7 +270,12 @@ protected Query doToQuery(QueryShardContext context) throws IOException { if (fieldType == null) { throw new IllegalStateException("Rewrite first"); } - return fieldType.prefixQuery(value, method, caseInsensitive, context); + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + return fieldType.prefixQuery(value, method, rewriteOverride, caseInsensitive, context); } @Override diff --git a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java index 3916eeb41e426..f905f6bb389f8 100644 --- a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java @@ -282,7 +282,12 @@ protected Query doToQuery(QueryShardContext context) throws IOException { } MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE); - return fieldType.wildcardQuery(value, method, caseInsensitive, context); + RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + rewrite_override, + RewriteOverride.DEFAULT, + LoggingDeprecationHandler.INSTANCE + ); + return fieldType.wildcardQuery(value, method, rewriteOverride, caseInsensitive, context); } @Override diff --git a/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java index 86f645957b78b..23b56a5fa4e87 100644 --- a/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java @@ -420,7 +420,7 @@ public void testFromJson() throws IOException { + " \"include_lower\" : true,\n" + " \"include_upper\" : true,\n" + " \"time_zone\" : \"+01:00\",\n" - + " \"boost\" : 1.0\n" + + " \"boost\" : 1.0,\n" + " \"rewrite_override\" : \"index_only\"\n" + " }\n" + " }\n" diff --git a/server/src/test/java/org/opensearch/index/query/RegexpQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/RegexpQueryBuilderTests.java index 80c87b5e85e30..f8140715cf566 100644 --- a/server/src/test/java/org/opensearch/index/query/RegexpQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/RegexpQueryBuilderTests.java @@ -122,7 +122,7 @@ public void testFromJson() throws IOException { + " \"flags_value\" : 7,\n" + " \"case_insensitive\" : true,\n" + " \"max_determinized_states\" : 20000,\n" - + " \"boost\" : 1.0\n" + + " \"boost\" : 1.0,\n" + " \"rewrite_override\" : \"index_only\"\n" + " }\n" + " }\n" From cf82097daa86a492ee1e6313f04bb2778e947142 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Fri, 9 Aug 2024 13:46:00 -0700 Subject: [PATCH 13/23] Fix missing comma Signed-off-by: Harsha Vamsi Kalluri --- .../java/org/opensearch/index/query/TermsQueryBuilderTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java index 9bed164fb2b3a..b81a7177b3bb9 100644 --- a/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java @@ -293,7 +293,7 @@ public void testFromJson() throws IOException { String json = "{\n" + " \"terms\" : {\n" + " \"user\" : [ \"foobar\", \"opensearch\" ],\n" - + " \"boost\" : 1.0\n" + + " \"boost\" : 1.0,\n" + " \"rewrite_override\": \"index_only\"\n" + " }\n" + "}"; From c9b921276747851a6b8cfc20a3f21fa23ad7e9d8 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Fri, 9 Aug 2024 14:09:51 -0700 Subject: [PATCH 14/23] Fix enum docs Signed-off-by: Harsha Vamsi Kalluri --- .../java/org/opensearch/index/mapper/RewriteOverride.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java b/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java index 966d8feebab17..bf495329773a7 100644 --- a/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java +++ b/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java @@ -10,11 +10,10 @@ import org.opensearch.common.annotation.PublicApi; -/* -* A custom rewrite override for a query. Default executes the query as is and other values determine which structure to use at run-time. +/** A custom rewrite override for a query. Default executes the query as is and other values determine which structure to use at run-time. * * @opensearch.internal -* */ +*/ @PublicApi(since = "2.17.0") public enum RewriteOverride { From dea3c0d1487739d077948cd6a0ce7962330b1156 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Wed, 14 Aug 2024 09:52:17 -0700 Subject: [PATCH 15/23] Address comments Signed-off-by: Harsha Vamsi Kalluri --- .../index/mapper/KeywordFieldMapper.java | 37 ++-- .../index/mapper/MappedFieldType.java | 16 +- .../index/mapper/RewriteOverride.java | 28 --- .../index/mapper/SimpleMappedFieldType.java | 4 +- .../index/mapper/StringFieldType.java | 6 +- .../index/query/FuzzyQueryBuilder.java | 5 +- .../index/query/PrefixQueryBuilder.java | 9 +- .../index/query/QueryRewriteContext.java | 17 ++ .../index/query/RangeQueryBuilder.java | 5 +- .../index/query/RegexpQueryBuilder.java | 5 +- .../index/query/TermsQueryBuilder.java | 5 +- .../index/query/WildcardQueryBuilder.java | 9 +- .../index/query/support/QueryParsers.java | 16 +- .../index/mapper/KeywordFieldTypeTests.java | 178 ++++++++++++++---- .../index/query/TermsQueryBuilderTests.java | 8 +- 15 files changed, 225 insertions(+), 123 deletions(-) delete mode 100644 server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java diff --git a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java index f2d4e5c6943e3..5a28706f46c68 100644 --- a/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java +++ b/server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java @@ -61,6 +61,7 @@ import org.opensearch.index.analysis.NamedAnalyzer; import org.opensearch.index.fielddata.IndexFieldData; import org.opensearch.index.fielddata.plain.SortedSetOrdinalsIndexFieldData; +import org.opensearch.index.query.QueryRewriteContext; import org.opensearch.index.query.QueryShardContext; import org.opensearch.index.similarity.SimilarityProvider; import org.opensearch.search.aggregations.support.CoreValuesSourceType; @@ -388,14 +389,14 @@ protected BytesRef indexedValueForSearch(Object value) { } @Override - public Query termsQuery(List values, RewriteOverride rewriteOverride, QueryShardContext context) { + public Query termsQuery(List values, QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context) { failIfNotIndexedAndNoDocValues(); if (rewriteOverride == null) { - rewriteOverride = RewriteOverride.DEFAULT; + rewriteOverride = QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES; } Query query = null; switch (rewriteOverride) { - case DEFAULT: + case INDEX_OR_DOC_VALUES: // has index and doc_values enabled if (isSearchable() && hasDocValues()) { BytesRef[] bytesRefs = new BytesRef[values.size()]; @@ -438,7 +439,7 @@ else if (hasDocValues()) { public Query prefixQuery( String value, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, boolean caseInsensitive, QueryShardContext context ) { @@ -452,11 +453,11 @@ public Query prefixQuery( } failIfNotIndexedAndNoDocValues(); if (rewriteOverride == null) { - rewriteOverride = RewriteOverride.DEFAULT; + rewriteOverride = QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES; } Query query = null; switch (rewriteOverride) { - case DEFAULT: + case INDEX_OR_DOC_VALUES: if (isSearchable() && hasDocValues()) { Query indexQuery = super.prefixQuery(value, method, caseInsensitive, context); Query dvQuery = super.prefixQuery(value, MultiTermQuery.DOC_VALUES_REWRITE, caseInsensitive, context); @@ -500,7 +501,7 @@ public Query regexpQuery( int matchFlags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { if (context.allowExpensiveQueries() == false) { @@ -510,11 +511,11 @@ public Query regexpQuery( } failIfNotIndexedAndNoDocValues(); if (rewriteOverride == null) { - rewriteOverride = RewriteOverride.DEFAULT; + rewriteOverride = QueryRewriteContext.RewriteOverride.INDEX_OR_DOC_VALUES; } Query query = null; switch (rewriteOverride) { - case DEFAULT: + case INDEX_OR_DOC_VALUES: if (isSearchable() && hasDocValues()) { Query indexQuery = super.regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); Query dvQuery = super.regexpQuery( @@ -564,7 +565,7 @@ public Query rangeQuery( Object upperTerm, boolean includeLower, boolean includeUpper, - RewriteOverride rewriteOverride, + QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { if (context.allowExpensiveQueries() == false) { @@ -576,11 +577,11 @@ public Query rangeQuery( } failIfNotIndexedAndNoDocValues(); if (rewriteOverride == null) { - rewriteOverride = RewriteOverride.DEFAULT; + rewriteOverride = QueryRewriteContext.RewriteOverride.INDEX_OR_DOC_VALUES; } Query query = null; switch (rewriteOverride) { - case DEFAULT: + case INDEX_OR_DOC_VALUES: if (isSearchable() && hasDocValues()) { Query indexQuery = new TermRangeQuery( name(), @@ -644,7 +645,7 @@ public Query fuzzyQuery( int maxExpansions, boolean transpositions, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { failIfNotIndexedAndNoDocValues(); @@ -654,11 +655,11 @@ public Query fuzzyQuery( ); } if (rewriteOverride == null) { - rewriteOverride = RewriteOverride.DEFAULT; + rewriteOverride = QueryRewriteContext.RewriteOverride.INDEX_OR_DOC_VALUES; } Query query = null; switch (rewriteOverride) { - case DEFAULT: + case INDEX_OR_DOC_VALUES: if (isSearchable() && hasDocValues()) { Query indexQuery = super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); Query dvQuery = super.fuzzyQuery( @@ -707,7 +708,7 @@ public Query fuzzyQuery( public Query wildcardQuery( String value, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, boolean caseInsensitive, QueryShardContext context ) { @@ -721,11 +722,11 @@ public Query wildcardQuery( // wildcard // query text if (rewriteOverride == null) { - rewriteOverride = RewriteOverride.DEFAULT; + rewriteOverride = QueryRewriteContext.RewriteOverride.INDEX_OR_DOC_VALUES; } Query query = null; switch (rewriteOverride) { - case DEFAULT: + case INDEX_OR_DOC_VALUES: if (isSearchable() && hasDocValues()) { Query indexQuery = super.wildcardQuery(value, method, caseInsensitive, true, context); Query dvQuery = super.wildcardQuery(value, MultiTermQuery.DOC_VALUES_REWRITE, caseInsensitive, true, context); diff --git a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java index 547c513ce3182..ab3cafd2516c1 100644 --- a/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/MappedFieldType.java @@ -230,7 +230,11 @@ public Query termQueryCaseInsensitive(Object value, @Nullable QueryShardContext ); } - public Query termsQuery(List values, @Nullable RewriteOverride rewriteOverride, @Nullable QueryShardContext context) { + public Query termsQuery( + List values, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, + @Nullable QueryShardContext context + ) { return termsQuery(values, context); } @@ -270,7 +274,7 @@ public Query rangeQuery( ShapeRelation relation, ZoneId timeZone, DateMathParser parser, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, relation, timeZone, parser, context); @@ -311,7 +315,7 @@ public Query fuzzyQuery( int maxExpansions, boolean transpositions, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { return fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); @@ -320,7 +324,7 @@ public Query fuzzyQuery( public Query prefixQuery( String value, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, boolean caseInsensitve, QueryShardContext context ) { @@ -365,7 +369,7 @@ public Query wildcardQuery( public Query wildcardQuery( String value, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, boolean caseInsensitve, QueryShardContext context ) { @@ -400,7 +404,7 @@ public Query regexpQuery( int matchFlags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { return regexpQuery(value, syntaxFlags, matchFlags, maxDeterminizedStates, method, context); diff --git a/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java b/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java deleted file mode 100644 index bf495329773a7..0000000000000 --- a/server/src/main/java/org/opensearch/index/mapper/RewriteOverride.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -package org.opensearch.index.mapper; - -import org.opensearch.common.annotation.PublicApi; - -/** A custom rewrite override for a query. Default executes the query as is and other values determine which structure to use at run-time. -* -* @opensearch.internal -*/ -@PublicApi(since = "2.17.0") -public enum RewriteOverride { - - // don't override the rewrite, use default - DEFAULT, - - // use index structure - INDEX_ONLY, - - // use doc_values structure - DOC_VALUES_ONLY -} diff --git a/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java b/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java index 3616458e8d123..815567e4cd263 100644 --- a/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/SimpleMappedFieldType.java @@ -88,7 +88,7 @@ public final Query rangeQuery( ShapeRelation relation, ZoneId timeZone, DateMathParser parser, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { if (relation == ShapeRelation.DISJOINT) { @@ -113,7 +113,7 @@ protected Query rangeQuery( Object upperTerm, boolean includeLower, boolean includeUpper, - RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context); diff --git a/server/src/main/java/org/opensearch/index/mapper/StringFieldType.java b/server/src/main/java/org/opensearch/index/mapper/StringFieldType.java index 08831b3d151f5..8cbb3872d98ea 100644 --- a/server/src/main/java/org/opensearch/index/mapper/StringFieldType.java +++ b/server/src/main/java/org/opensearch/index/mapper/StringFieldType.java @@ -141,7 +141,7 @@ public Query fuzzyQuery( int maxExpansions, boolean transpositions, @Nullable MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { return fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context); @@ -207,7 +207,7 @@ public Query wildcardQuery(String value, MultiTermQuery.RewriteMethod method, bo public Query wildcardQuery( String value, MultiTermQuery.RewriteMethod method, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, boolean caseInsensitive, QueryShardContext context ) { @@ -312,7 +312,7 @@ public Query rangeQuery( Object upperTerm, boolean includeLower, boolean includeUpper, - @Nullable RewriteOverride rewriteOverride, + @Nullable QueryShardContext.RewriteOverride rewriteOverride, QueryShardContext context ) { return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context); diff --git a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java index cf774fef0e88c..b982f4d059ecd 100644 --- a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java @@ -46,7 +46,6 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.mapper.MappedFieldType; -import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -381,9 +380,9 @@ protected Query doToQuery(QueryShardContext context) throws IOException { throw new IllegalStateException("Rewrite first"); } String rewrite = this.rewrite; - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( rewrite_override, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); Query query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, null, rewriteOverride, context); diff --git a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java index 2e6212f5b0948..1b1cb179368b7 100644 --- a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java @@ -47,7 +47,6 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; -import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -242,9 +241,9 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws // This logic is correct for all field types, but by only applying it to constant // fields we also have the guarantee that it doesn't perform I/O, which is important // since rewrites might happen on a network thread. - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( rewrite_override, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); Query query = fieldType.prefixQuery(value, null, rewriteOverride, caseInsensitive, context); // the rewrite method doesn't @@ -270,9 +269,9 @@ protected Query doToQuery(QueryShardContext context) throws IOException { if (fieldType == null) { throw new IllegalStateException("Rewrite first"); } - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( rewrite_override, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); return fieldType.prefixQuery(value, method, rewriteOverride, caseInsensitive, context); diff --git a/server/src/main/java/org/opensearch/index/query/QueryRewriteContext.java b/server/src/main/java/org/opensearch/index/query/QueryRewriteContext.java index 15a6d0b5a774e..8994f3d9d8770 100644 --- a/server/src/main/java/org/opensearch/index/query/QueryRewriteContext.java +++ b/server/src/main/java/org/opensearch/index/query/QueryRewriteContext.java @@ -159,4 +159,21 @@ public void onFailure(Exception e) { public boolean validate() { return validate; } + + /** A custom rewrite override for a query. Default executes the query as is and other values determine which structure to use at run-time. + * + * @opensearch.internal + */ + @PublicApi(since = "2.17.0") + public enum RewriteOverride { + + // don't override the rewrite, use default + INDEX_OR_DOC_VALUES, + + // use index structure + INDEX_ONLY, + + // use doc_values structure + DOC_VALUES_ONLY + } } diff --git a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java index 4922c65ee624f..c07319c9f49ea 100644 --- a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java @@ -49,7 +49,6 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.mapper.FieldNamesFieldMapper; import org.opensearch.index.mapper.MappedFieldType; -import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -549,9 +548,9 @@ protected Query doToQuery(QueryShardContext context) throws IOException { throw new IllegalStateException("Rewrite first"); } DateMathParser forcedDateParser = getForceDateParser(); - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( rewrite_override, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); return mapper.rangeQuery(from, to, includeLower, includeUpper, relation, timeZone, forcedDateParser, rewriteOverride, context); diff --git a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java index 0c68c7b57fcf9..c2ddb622d631a 100644 --- a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java @@ -50,7 +50,6 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.IndexSettings; import org.opensearch.index.mapper.MappedFieldType; -import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -327,9 +326,9 @@ protected Query doToQuery(QueryShardContext context) throws QueryShardException, MappedFieldType fieldType = context.fieldMapper(fieldName); if (fieldType != null) { - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( rewrite_override, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); query = fieldType.regexpQuery( diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index 31f9e85500c50..ac09420c623f3 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -56,7 +56,6 @@ import org.opensearch.index.IndexSettings; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; -import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import org.opensearch.indices.TermsLookup; @@ -510,9 +509,9 @@ protected Query doToQuery(QueryShardContext context) throws IOException { if (fieldType == null) { throw new IllegalStateException("Rewrite first"); } - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( rewrite_override, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); return fieldType.termsQuery(values, rewriteOverride, context); diff --git a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java index f905f6bb389f8..733111398cc70 100644 --- a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java @@ -47,7 +47,6 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; -import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.index.query.support.QueryParsers; import java.io.IOException; @@ -253,9 +252,9 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws // This logic is correct for all field types, but by only applying it to constant // fields we also have the guarantee that it doesn't perform I/O, which is important // since rewrites might happen on a network thread. - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( rewrite_override, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); Query query = fieldType.wildcardQuery(value, null, rewriteOverride, caseInsensitive, context); // the rewrite method doesn't @@ -282,9 +281,9 @@ protected Query doToQuery(QueryShardContext context) throws IOException { } MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE); - RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( rewrite_override, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); return fieldType.wildcardQuery(value, method, rewriteOverride, caseInsensitive, context); diff --git a/server/src/main/java/org/opensearch/index/query/support/QueryParsers.java b/server/src/main/java/org/opensearch/index/query/support/QueryParsers.java index 43c5b0ceb2a89..9fe5f6d805ef0 100644 --- a/server/src/main/java/org/opensearch/index/query/support/QueryParsers.java +++ b/server/src/main/java/org/opensearch/index/query/support/QueryParsers.java @@ -36,7 +36,7 @@ import org.opensearch.common.Nullable; import org.opensearch.core.ParseField; import org.opensearch.core.xcontent.DeprecationHandler; -import org.opensearch.index.mapper.RewriteOverride; +import org.opensearch.index.query.QueryShardContext; /** * Utility class for Query Parsers @@ -52,7 +52,7 @@ public final class QueryParsers { public static final ParseField TOP_TERMS_BOOST = new ParseField("top_terms_boost_"); public static final ParseField TOP_TERMS_BLENDED_FREQS = new ParseField("top_terms_blended_freqs_"); - public static final ParseField DEFAULT = new ParseField("default"); + public static final ParseField INDEX_OR_DOC_VALUES = new ParseField("index_or_doc_values"); public static final ParseField INDEX_ONLY = new ParseField("index_only"); public static final ParseField DOC_VALUES_ONLY = new ParseField("doc_values_only"); @@ -71,22 +71,22 @@ public static MultiTermQuery.RewriteMethod parseRewriteMethod(@Nullable String r return parseRewriteMethod(rewriteMethod, MultiTermQuery.CONSTANT_SCORE_REWRITE, deprecationHandler); } - public static RewriteOverride parseRewriteOverride( + public static QueryShardContext.RewriteOverride parseRewriteOverride( @Nullable String rewrite_override, - @Nullable RewriteOverride defaultRewriteOverride, + @Nullable QueryShardContext.RewriteOverride defaultRewriteOverride, DeprecationHandler deprecationHandler ) { if (rewrite_override == null) { return defaultRewriteOverride; } - if (DEFAULT.match(rewrite_override, deprecationHandler)) { - return RewriteOverride.DEFAULT; + if (INDEX_OR_DOC_VALUES.match(rewrite_override, deprecationHandler)) { + return QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES; } if (INDEX_ONLY.match(rewrite_override, deprecationHandler)) { - return RewriteOverride.INDEX_ONLY; + return QueryShardContext.RewriteOverride.INDEX_ONLY; } if (DOC_VALUES_ONLY.match(rewrite_override, deprecationHandler)) { - return RewriteOverride.DOC_VALUES_ONLY; + return QueryShardContext.RewriteOverride.DOC_VALUES_ONLY; } throw new IllegalArgumentException("Failed to parse rewrite_override [" + rewrite_override + "]"); diff --git a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java index 89cc4326eafbe..35c8f2d24e64b 100644 --- a/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java +++ b/server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java @@ -72,6 +72,7 @@ import org.opensearch.index.analysis.TokenizerFactory; import org.opensearch.index.mapper.KeywordFieldMapper.KeywordFieldType; import org.opensearch.index.mapper.MappedFieldType.Relation; +import org.opensearch.index.query.QueryShardContext; import java.io.IOException; import java.util.ArrayList; @@ -136,22 +137,34 @@ public void testTermsQuery() { new TermInSetQuery("field", terms), new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, "field", terms) ); - assertEquals(expected, ft.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null)); + assertEquals(expected, ft.termsQuery(Arrays.asList("foo", "bar"), QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, null)); MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); Query expectedIndex = new TermInSetQuery("field", terms); - assertEquals(expectedIndex, onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null)); - assertEquals(expectedIndex, onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.INDEX_ONLY, null)); + assertEquals( + expectedIndex, + onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, null) + ); + assertEquals( + expectedIndex, + onlyIndexed.termsQuery(Arrays.asList("foo", "bar"), QueryShardContext.RewriteOverride.INDEX_ONLY, null) + ); MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); Query expectedDocValues = new TermInSetQuery(MultiTermQuery.DOC_VALUES_REWRITE, "field", terms); - assertEquals(expectedDocValues, onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null)); - assertEquals(expectedDocValues, onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DOC_VALUES_ONLY, null)); + assertEquals( + expectedDocValues, + onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, null) + ); + assertEquals( + expectedDocValues, + onlyDocValues.termsQuery(Arrays.asList("foo", "bar"), QueryShardContext.RewriteOverride.DOC_VALUES_ONLY, null) + ); MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"), RewriteOverride.DEFAULT, null) + () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"), QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, null) ); assertEquals( "Cannot search on field [field] since it is both not indexed, and does not have doc_values " + "enabled.", @@ -190,21 +203,33 @@ public void testRangeQuery() { ); Query expected = new IndexOrDocValuesQuery(indexExpected, dvExpected); - Query actual = ft.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC); + Query actual = ft.rangeQuery("foo", "bar", true, false, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC); assertEquals(expected, actual); KeywordFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); - assertEquals(indexExpected, onlyIndexed.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC)); - assertEquals(indexExpected, onlyIndexed.rangeQuery("foo", "bar", true, false, RewriteOverride.INDEX_ONLY, MOCK_QSC)); + assertEquals( + indexExpected, + onlyIndexed.rangeQuery("foo", "bar", true, false, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC) + ); + assertEquals( + indexExpected, + onlyIndexed.rangeQuery("foo", "bar", true, false, QueryShardContext.RewriteOverride.INDEX_ONLY, MOCK_QSC) + ); KeywordFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); - assertEquals(dvExpected, onlyDocValues.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC)); - assertEquals(dvExpected, onlyDocValues.rangeQuery("foo", "bar", true, false, RewriteOverride.DOC_VALUES_ONLY, MOCK_QSC)); + assertEquals( + dvExpected, + onlyDocValues.rangeQuery("foo", "bar", true, false, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC) + ); + assertEquals( + dvExpected, + onlyDocValues.rangeQuery("foo", "bar", true, false, QueryShardContext.RewriteOverride.DOC_VALUES_ONLY, MOCK_QSC) + ); KeywordFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC) + () -> unsearchable.rangeQuery("foo", "bar", true, false, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC) ); assertEquals( @@ -214,7 +239,14 @@ public void testRangeQuery() { OpenSearchException ee = expectThrows( OpenSearchException.class, - () -> ft.rangeQuery("foo", "bar", true, false, RewriteOverride.DEFAULT, MOCK_QSC_DISALLOW_EXPENSIVE) + () -> ft.rangeQuery( + "foo", + "bar", + true, + false, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, + MOCK_QSC_DISALLOW_EXPENSIVE + ) ); assertEquals( "[range] queries on [text] or [keyword] fields cannot be executed when " + "'search.allow_expensive_queries' is set to false.", @@ -229,18 +261,42 @@ public void testRegexpQuery() { new RegexpQuery(new Term("field", "foo.*")), new RegexpQuery(new Term("field", "foo.*"), 0, 0, RegexpQuery.DEFAULT_PROVIDER, 10, MultiTermQuery.DOC_VALUES_REWRITE) ), - ft.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.DEFAULT, MOCK_QSC) + ft.regexpQuery( + "foo.*", + 0, + 0, + 10, + MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, + MOCK_QSC + ) ); Query indexExpected = new RegexpQuery(new Term("field", "foo.*")); MappedFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); assertEquals( indexExpected, - onlyIndexed.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.DEFAULT, MOCK_QSC) + onlyIndexed.regexpQuery( + "foo.*", + 0, + 0, + 10, + MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, + MOCK_QSC + ) ); assertEquals( indexExpected, - onlyIndexed.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.INDEX_ONLY, MOCK_QSC) + onlyIndexed.regexpQuery( + "foo.*", + 0, + 0, + 10, + MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, + QueryShardContext.RewriteOverride.INDEX_ONLY, + MOCK_QSC + ) ); Query dvExpected = new RegexpQuery( @@ -254,17 +310,33 @@ public void testRegexpQuery() { MappedFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); assertEquals( dvExpected, - onlyDocValues.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.DOC_VALUES_REWRITE, RewriteOverride.DEFAULT, MOCK_QSC) + onlyDocValues.regexpQuery( + "foo.*", + 0, + 0, + 10, + MultiTermQuery.DOC_VALUES_REWRITE, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, + MOCK_QSC + ) ); assertEquals( dvExpected, - onlyDocValues.regexpQuery("foo.*", 0, 0, 10, MultiTermQuery.DOC_VALUES_REWRITE, RewriteOverride.DOC_VALUES_ONLY, MOCK_QSC) + onlyDocValues.regexpQuery( + "foo.*", + 0, + 0, + 10, + MultiTermQuery.DOC_VALUES_REWRITE, + QueryShardContext.RewriteOverride.DOC_VALUES_ONLY, + MOCK_QSC + ) ); MappedFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> unsearchable.regexpQuery("foo.*", 0, 0, 10, null, RewriteOverride.DEFAULT, MOCK_QSC) + () -> unsearchable.regexpQuery("foo.*", 0, 0, 10, null, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC) ); assertEquals( "Cannot search on field [field] since it is both not indexed, and does not have doc_values " + "enabled.", @@ -273,7 +345,15 @@ public void testRegexpQuery() { OpenSearchException ee = expectThrows( OpenSearchException.class, - () -> ft.regexpQuery("foo.*", randomInt(10), 0, randomInt(10) + 1, null, RewriteOverride.DEFAULT, MOCK_QSC_DISALLOW_EXPENSIVE) + () -> ft.regexpQuery( + "foo.*", + randomInt(10), + 0, + randomInt(10) + 1, + null, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, + MOCK_QSC_DISALLOW_EXPENSIVE + ) ); assertEquals("[regexp] queries cannot be executed when 'search.allow_expensive_queries' is set to false.", ee.getMessage()); } @@ -285,7 +365,7 @@ public void testFuzzyQuery() { new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true), new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true, MultiTermQuery.DOC_VALUES_REWRITE) ), - ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, null, RewriteOverride.DEFAULT, MOCK_QSC) + ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, null, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC) ); Query indexExpected = new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true); @@ -299,7 +379,7 @@ public void testFuzzyQuery() { 50, true, FuzzyQuery.defaultRewriteMethod(50), - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC ) ); @@ -312,7 +392,7 @@ public void testFuzzyQuery() { 50, true, FuzzyQuery.defaultRewriteMethod(50), - RewriteOverride.INDEX_ONLY, + QueryShardContext.RewriteOverride.INDEX_ONLY, MOCK_QSC ) ); @@ -328,7 +408,7 @@ public void testFuzzyQuery() { 50, true, MultiTermQuery.DOC_VALUES_REWRITE, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC ) ); @@ -341,7 +421,7 @@ public void testFuzzyQuery() { 50, true, MultiTermQuery.DOC_VALUES_REWRITE, - RewriteOverride.DOC_VALUES_ONLY, + QueryShardContext.RewriteOverride.DOC_VALUES_ONLY, MOCK_QSC ) ); @@ -356,7 +436,7 @@ public void testFuzzyQuery() { 50, true, MultiTermQuery.DOC_VALUES_REWRITE, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC ) ); @@ -374,7 +454,7 @@ public void testFuzzyQuery() { randomInt(10) + 1, randomBoolean(), FuzzyQuery.defaultRewriteMethod(randomInt(10) + 1), - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, MOCK_QSC_DISALLOW_EXPENSIVE ) ); @@ -393,18 +473,36 @@ public void testWildCardQuery() { ); assertEquals( expected, - ft.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.DEFAULT, false, MOCK_QSC) + ft.wildcardQuery( + "foo*", + MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, + false, + MOCK_QSC + ) ); Query indexExpected = new WildcardQuery(new Term("field", new BytesRef("foo*"))); KeywordFieldType onlyIndexed = new KeywordFieldType("field", true, false, Collections.emptyMap()); assertEquals( indexExpected, - onlyIndexed.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.DEFAULT, false, MOCK_QSC) + onlyIndexed.wildcardQuery( + "foo*", + MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, + false, + MOCK_QSC + ) ); assertEquals( indexExpected, - onlyIndexed.wildcardQuery("foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, RewriteOverride.INDEX_ONLY, false, MOCK_QSC) + onlyIndexed.wildcardQuery( + "foo*", + MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, + QueryShardContext.RewriteOverride.INDEX_ONLY, + false, + MOCK_QSC + ) ); Query dvExpected = new WildcardQuery( @@ -415,11 +513,23 @@ public void testWildCardQuery() { KeywordFieldType onlyDocValues = new KeywordFieldType("field", false, true, Collections.emptyMap()); assertEquals( dvExpected, - onlyDocValues.wildcardQuery("foo*", MultiTermQuery.DOC_VALUES_REWRITE, RewriteOverride.DEFAULT, false, MOCK_QSC) + onlyDocValues.wildcardQuery( + "foo*", + MultiTermQuery.DOC_VALUES_REWRITE, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, + false, + MOCK_QSC + ) ); assertEquals( dvExpected, - onlyDocValues.wildcardQuery("foo*", MultiTermQuery.DOC_VALUES_REWRITE, RewriteOverride.DOC_VALUES_ONLY, false, MOCK_QSC) + onlyDocValues.wildcardQuery( + "foo*", + MultiTermQuery.DOC_VALUES_REWRITE, + QueryShardContext.RewriteOverride.DOC_VALUES_ONLY, + false, + MOCK_QSC + ) ); KeywordFieldType unsearchable = new KeywordFieldType("field", false, false, Collections.emptyMap()); @@ -428,7 +538,7 @@ public void testWildCardQuery() { () -> unsearchable.wildcardQuery( "foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, false, MOCK_QSC ) @@ -443,7 +553,7 @@ public void testWildCardQuery() { () -> ft.wildcardQuery( "foo*", MultiTermQuery.CONSTANT_SCORE_BLENDED_REWRITE, - RewriteOverride.DEFAULT, + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, false, MOCK_QSC_DISALLOW_EXPENSIVE ) diff --git a/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java index b81a7177b3bb9..bc9779178c012 100644 --- a/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java +++ b/server/src/test/java/org/opensearch/index/query/TermsQueryBuilderTests.java @@ -53,7 +53,6 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.get.GetResult; -import org.opensearch.index.mapper.RewriteOverride; import org.opensearch.indices.TermsLookup; import org.opensearch.test.AbstractQueryTestCase; import org.hamcrest.CoreMatchers; @@ -365,7 +364,12 @@ public void testConversion() { } public void testRewriteIndexQueryToMatchNone() throws IOException { - TermsQueryBuilder query = new TermsQueryBuilder("_index", "does_not_exist", "also_does_not_exist", RewriteOverride.DEFAULT); + TermsQueryBuilder query = new TermsQueryBuilder( + "_index", + "does_not_exist", + "also_does_not_exist", + QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES + ); QueryShardContext queryShardContext = createShardContext(); QueryBuilder rewritten = query.rewrite(queryShardContext); assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class)); From 1a27ec3bbbf304a39d04d9fcc998f10de5d23182 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Mon, 19 Aug 2024 13:51:54 -0700 Subject: [PATCH 16/23] Address comments Signed-off-by: Harsha Vamsi Kalluri --- .../index/query/FuzzyQueryBuilder.java | 45 ++++++++++-------- .../index/query/PrefixQueryBuilder.java | 36 +++++++-------- .../index/query/RangeQueryBuilder.java | 44 +++++++++++------- .../index/query/RegexpQueryBuilder.java | 34 +++++++------- .../index/query/TermsQueryBuilder.java | 46 +++++++++---------- .../index/query/WildcardQueryBuilder.java | 43 ++++++++--------- 6 files changed, 134 insertions(+), 114 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java index b982f4d059ecd..3f4d3dd974967 100644 --- a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java @@ -81,7 +81,7 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder i private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); - private String rewrite_override; + private String rewriteOverride; private final String fieldName; @@ -186,8 +186,8 @@ public FuzzyQueryBuilder(StreamInput in) throws IOException { maxExpansions = in.readVInt(); transpositions = in.readBoolean(); rewrite = in.readOptionalString(); - if (in.getVersion().after(Version.V_2_16_0)) { - rewrite_override = in.readOptionalString(); + if (in.getVersion().onOrAfter(Version.V_2_17_0)) { + rewriteOverride = in.readOptionalString(); } } @@ -200,8 +200,8 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeVInt(this.maxExpansions); out.writeBoolean(this.transpositions); out.writeOptionalString(this.rewrite); - if (out.getVersion().after(Version.V_2_16_0)) { - out.writeOptionalString(rewrite_override); + if (out.getVersion().onOrAfter(Version.V_2_17_0)) { + out.writeOptionalString(rewriteOverride); } } @@ -259,8 +259,8 @@ public String rewrite() { return this.rewrite; } - private FuzzyQueryBuilder rewrite_override(String rewrite_override) { - this.rewrite_override = rewrite_override; + private FuzzyQueryBuilder rewriteOverride(String rewriteOverride) { + this.rewriteOverride = rewriteOverride; return this; } @@ -277,8 +277,8 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep builder.field(REWRITE_FIELD.getPreferredName(), rewrite); } printBoostAndQueryName(builder); - if (rewrite_override != null) { - builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + if (rewriteOverride != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewriteOverride); } builder.endObject(); builder.endObject(); @@ -292,7 +292,7 @@ public static FuzzyQueryBuilder fromXContent(XContentParser parser) throws IOExc int maxExpansions = FuzzyQueryBuilder.DEFAULT_MAX_EXPANSIONS; boolean transpositions = FuzzyQueryBuilder.DEFAULT_TRANSPOSITIONS; String rewrite = null; - String rewrite_override = null; + String rewriteOverride = null; String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; String currentFieldName = null; @@ -324,7 +324,7 @@ public static FuzzyQueryBuilder fromXContent(XContentParser parser) throws IOExc } else if (REWRITE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { rewrite = parser.textOrNull(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { - rewrite_override = parser.textOrNull(); + rewriteOverride = parser.textOrNull(); } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); } else { @@ -353,7 +353,7 @@ public static FuzzyQueryBuilder fromXContent(XContentParser parser) throws IOExc .rewrite(rewrite) .boost(boost) .queryName(queryName) - .rewrite_override(rewrite_override); + .rewriteOverride(rewriteOverride); } @Override @@ -380,12 +380,21 @@ protected Query doToQuery(QueryShardContext context) throws IOException { throw new IllegalStateException("Rewrite first"); } String rewrite = this.rewrite; - QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( - rewrite_override, + QueryShardContext.RewriteOverride rewriteOverrideMethod = QueryParsers.parseRewriteOverride( + rewriteOverride, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); - Query query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, null, rewriteOverride, context); + Query query = fieldType.fuzzyQuery( + value, + fuzziness, + prefixLength, + maxExpansions, + transpositions, + null, + rewriteOverrideMethod, + context + ); if (query instanceof MultiTermQuery) { MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE); query = fieldType.fuzzyQuery( @@ -395,7 +404,7 @@ protected Query doToQuery(QueryShardContext context) throws IOException { maxExpansions, transpositions, rewriteMethod, - rewriteOverride, + rewriteOverrideMethod, context ); } @@ -404,7 +413,7 @@ protected Query doToQuery(QueryShardContext context) throws IOException { @Override protected int doHashCode() { - return Objects.hash(fieldName, value, fuzziness, prefixLength, maxExpansions, transpositions, rewrite, rewrite_override); + return Objects.hash(fieldName, value, fuzziness, prefixLength, maxExpansions, transpositions, rewrite, rewriteOverride); } @Override @@ -416,6 +425,6 @@ protected boolean doEquals(FuzzyQueryBuilder other) { && Objects.equals(maxExpansions, other.maxExpansions) && Objects.equals(transpositions, other.transpositions) && Objects.equals(rewrite, other.rewrite) - && Objects.equals(rewrite_override, other.rewrite_override); + && Objects.equals(rewriteOverride, other.rewriteOverride); } } diff --git a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java index 1b1cb179368b7..6e5963ad63034 100644 --- a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java @@ -65,7 +65,7 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); - private String rewrite_override; + private String rewriteOverride; private final String fieldName; @@ -103,8 +103,8 @@ public PrefixQueryBuilder(StreamInput in) throws IOException { value = in.readString(); rewrite = in.readOptionalString(); caseInsensitive = in.readBoolean(); - if (in.getVersion().after(Version.V_2_16_0)) { - rewrite_override = in.readOptionalString(); + if (in.getVersion().onOrAfter(Version.V_2_17_0)) { + rewriteOverride = in.readOptionalString(); } } @@ -114,8 +114,8 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(value); out.writeOptionalString(rewrite); out.writeBoolean(caseInsensitive); - if (out.getVersion().after(Version.V_2_16_0)) { - out.writeOptionalString(rewrite_override); + if (out.getVersion().onOrAfter(Version.V_2_17_0)) { + out.writeOptionalString(rewriteOverride); } } @@ -142,8 +142,8 @@ public PrefixQueryBuilder rewrite(String rewrite) { return this; } - public PrefixQueryBuilder rewrite_override(String rewrite_override) { - this.rewrite_override = rewrite_override; + public PrefixQueryBuilder rewriteOverride(String rewriteOverride) { + this.rewriteOverride = rewriteOverride; return this; } @@ -163,8 +163,8 @@ public void doXContent(XContentBuilder builder, Params params) throws IOExceptio builder.field(CASE_INSENSITIVE_FIELD.getPreferredName(), caseInsensitive); } printBoostAndQueryName(builder); - if (rewrite_override != null) { - builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + if (rewriteOverride != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewriteOverride); } builder.endObject(); builder.endObject(); @@ -174,7 +174,7 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx String fieldName = null; String value = null; String rewrite = null; - String rewrite_override = null; + String rewriteOverride = null; String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; @@ -202,7 +202,7 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx } else if (CASE_INSENSITIVE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { caseInsensitive = parser.booleanValue(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { - rewrite_override = parser.textOrNull(); + rewriteOverride = parser.textOrNull(); } else { throw new ParsingException( parser.getTokenLocation(), @@ -222,7 +222,7 @@ public static PrefixQueryBuilder fromXContent(XContentParser parser) throws IOEx .boost(boost) .queryName(queryName) .caseInsensitive(caseInsensitive) - .rewrite_override(rewrite_override); + .rewriteOverride(rewriteOverride); } @Override @@ -242,7 +242,7 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws // fields we also have the guarantee that it doesn't perform I/O, which is important // since rewrites might happen on a network thread. QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( - rewrite_override, + rewriteOverride, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); @@ -269,17 +269,17 @@ protected Query doToQuery(QueryShardContext context) throws IOException { if (fieldType == null) { throw new IllegalStateException("Rewrite first"); } - QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( - rewrite_override, + QueryShardContext.RewriteOverride rewriteOverrideMethod = QueryParsers.parseRewriteOverride( + rewriteOverride, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); - return fieldType.prefixQuery(value, method, rewriteOverride, caseInsensitive, context); + return fieldType.prefixQuery(value, method, rewriteOverrideMethod, caseInsensitive, context); } @Override protected final int doHashCode() { - return Objects.hash(fieldName, value, rewrite, caseInsensitive, rewrite_override); + return Objects.hash(fieldName, value, rewrite, caseInsensitive, rewriteOverride); } @Override @@ -287,7 +287,7 @@ protected boolean doEquals(PrefixQueryBuilder other) { return Objects.equals(fieldName, other.fieldName) && Objects.equals(value, other.value) && Objects.equals(rewrite, other.rewrite) - && Objects.equals(rewrite_override, other.rewrite_override) + && Objects.equals(rewriteOverride, other.rewriteOverride) && Objects.equals(caseInsensitive, other.caseInsensitive); } } diff --git a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java index c07319c9f49ea..7973c0eef97c5 100644 --- a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java @@ -89,7 +89,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder i private String format; private ShapeRelation relation; - private String rewrite_override; + private String rewriteOverride; /** * A Query that matches documents within an range of terms. @@ -122,8 +122,8 @@ public RangeQueryBuilder(StreamInput in) throws IOException { throw new IllegalArgumentException("[range] query does not support relation [" + relationString + "]"); } } - if (in.getVersion().after(Version.V_2_16_0)) { - rewrite_override = in.readOptionalString(); + if (in.getVersion().after(Version.V_2_17_0)) { + rewriteOverride = in.readOptionalString(); } } @@ -145,8 +145,8 @@ protected void doWriteTo(StreamOutput out) throws IOException { relationString = this.relation.getRelationName(); } out.writeOptionalString(relationString); - if (out.getVersion().after(Version.V_2_16_0)) { - out.writeOptionalString(rewrite_override); + if (out.getVersion().after(Version.V_2_17_0)) { + out.writeOptionalString(rewriteOverride); } } @@ -283,8 +283,8 @@ public RangeQueryBuilder timeZone(String timeZone) { return this; } - public RangeQueryBuilder rewrite_override(String rewrite_override) { - this.rewrite_override = rewrite_override; + public RangeQueryBuilder rewriteOverride(String rewriteOverride) { + this.rewriteOverride = rewriteOverride; return this; } @@ -362,8 +362,8 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep builder.field(RELATION_FIELD.getPreferredName(), relation.getRelationName()); } printBoostAndQueryName(builder); - if (rewrite_override != null) { - builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + if (rewriteOverride != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewriteOverride); } builder.endObject(); builder.endObject(); @@ -380,7 +380,7 @@ public static RangeQueryBuilder fromXContent(XContentParser parser) throws IOExc String queryName = null; String format = null; String relation = null; - String rewrite_override = null; + String rewriteOverride = null; String currentFieldName = null; XContentParser.Token token; @@ -425,7 +425,7 @@ public static RangeQueryBuilder fromXContent(XContentParser parser) throws IOExc } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { - rewrite_override = parser.textOrNull(); + rewriteOverride = parser.textOrNull(); } else { throw new ParsingException( parser.getTokenLocation(), @@ -455,7 +455,7 @@ public static RangeQueryBuilder fromXContent(XContentParser parser) throws IOExc if (relation != null) { rangeQuery.relation(relation); } - rangeQuery.rewrite_override(rewrite_override); + rangeQuery.rewriteOverride(rewriteOverride); return rangeQuery; } @@ -548,17 +548,27 @@ protected Query doToQuery(QueryShardContext context) throws IOException { throw new IllegalStateException("Rewrite first"); } DateMathParser forcedDateParser = getForceDateParser(); - QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( - rewrite_override, + QueryShardContext.RewriteOverride rewriteOverrideMethod = QueryParsers.parseRewriteOverride( + rewriteOverride, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); - return mapper.rangeQuery(from, to, includeLower, includeUpper, relation, timeZone, forcedDateParser, rewriteOverride, context); + return mapper.rangeQuery( + from, + to, + includeLower, + includeUpper, + relation, + timeZone, + forcedDateParser, + rewriteOverrideMethod, + context + ); } @Override protected int doHashCode() { - return Objects.hash(fieldName, from, to, timeZone, includeLower, includeUpper, format, rewrite_override); + return Objects.hash(fieldName, from, to, timeZone, includeLower, includeUpper, format, rewriteOverride); } @Override @@ -570,6 +580,6 @@ protected boolean doEquals(RangeQueryBuilder other) { && Objects.equals(includeLower, other.includeLower) && Objects.equals(includeUpper, other.includeUpper) && Objects.equals(format, other.format) - && Objects.equals(rewrite_override, other.rewrite_override); + && Objects.equals(rewriteOverride, other.rewriteOverride); } } diff --git a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java index c2ddb622d631a..01fe387e00196 100644 --- a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java @@ -76,7 +76,7 @@ public class RegexpQueryBuilder extends AbstractQueryBuilder private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); - private String rewrite_override; + private String rewriteOverride; private final String fieldName; @@ -117,8 +117,8 @@ public RegexpQueryBuilder(StreamInput in) throws IOException { maxDeterminizedStates = in.readVInt(); rewrite = in.readOptionalString(); caseInsensitive = in.readBoolean(); - if (in.getVersion().after(Version.V_2_16_0)) { - rewrite_override = in.readOptionalString(); + if (in.getVersion().after(Version.V_2_17_0)) { + rewriteOverride = in.readOptionalString(); } } @@ -130,8 +130,8 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeVInt(maxDeterminizedStates); out.writeOptionalString(rewrite); out.writeBoolean(caseInsensitive); - if (out.getVersion().after(Version.V_2_16_0)) { - out.writeOptionalString(rewrite_override); + if (out.getVersion().after(Version.V_2_17_0)) { + out.writeOptionalString(rewriteOverride); } } @@ -183,8 +183,8 @@ public boolean caseInsensitive() { return this.caseInsensitive; } - public RegexpQueryBuilder rewrite_override(String rewrite_override) { - this.rewrite_override = rewrite_override; + public RegexpQueryBuilder rewriteOverride(String rewriteOverride) { + this.rewriteOverride = rewriteOverride; return this; } @@ -223,8 +223,8 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep builder.field(REWRITE_FIELD.getPreferredName(), rewrite); } printBoostAndQueryName(builder); - if (rewrite_override != null) { - builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + if (rewriteOverride != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewriteOverride); } builder.endObject(); builder.endObject(); @@ -234,7 +234,7 @@ public static RegexpQueryBuilder fromXContent(XContentParser parser) throws IOEx String fieldName = null; String rewrite = null; String value = null; - String rewrite_override = null; + String rewriteOverride = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; int flagsValue = RegexpQueryBuilder.DEFAULT_FLAGS_VALUE; boolean caseInsensitive = DEFAULT_CASE_INSENSITIVITY; @@ -270,7 +270,7 @@ public static RegexpQueryBuilder fromXContent(XContentParser parser) throws IOEx } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { - rewrite_override = parser.textOrNull(); + rewriteOverride = parser.textOrNull(); } else { throw new ParsingException( parser.getTokenLocation(), @@ -292,7 +292,7 @@ public static RegexpQueryBuilder fromXContent(XContentParser parser) throws IOEx .boost(boost) .queryName(queryName); result.caseInsensitive(caseInsensitive); - result.rewrite_override(rewrite_override); + result.rewriteOverride(rewriteOverride); return result; } @@ -326,8 +326,8 @@ protected Query doToQuery(QueryShardContext context) throws QueryShardException, MappedFieldType fieldType = context.fieldMapper(fieldName); if (fieldType != null) { - QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( - rewrite_override, + QueryShardContext.RewriteOverride rewriteOverrideMethod = QueryParsers.parseRewriteOverride( + rewriteOverride, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); @@ -337,7 +337,7 @@ protected Query doToQuery(QueryShardContext context) throws QueryShardException, matchFlagsValue, maxDeterminizedStates, method, - rewriteOverride, + rewriteOverrideMethod, context ); } @@ -359,7 +359,7 @@ protected Query doToQuery(QueryShardContext context) throws QueryShardException, @Override protected int doHashCode() { - return Objects.hash(fieldName, value, syntaxFlagsValue, caseInsensitive, maxDeterminizedStates, rewrite, rewrite_override); + return Objects.hash(fieldName, value, syntaxFlagsValue, caseInsensitive, maxDeterminizedStates, rewrite, rewriteOverride); } @Override @@ -370,6 +370,6 @@ protected boolean doEquals(RegexpQueryBuilder other) { && Objects.equals(caseInsensitive, other.caseInsensitive) && Objects.equals(maxDeterminizedStates, other.maxDeterminizedStates) && Objects.equals(rewrite, other.rewrite) - && Objects.equals(rewrite_override, other.rewrite_override); + && Objects.equals(rewriteOverride, other.rewriteOverride); } } diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index ac09420c623f3..f08a84e7d58e2 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -88,7 +88,7 @@ public class TermsQueryBuilder extends AbstractQueryBuilder { private static final ParseField REWRITE_OVERRIDE = new ParseField("rewrite_override"); - private String rewrite_override; + private String rewriteOverride; public TermsQueryBuilder(String fieldName, TermsLookup termsLookup) { this(fieldName, null, termsLookup); @@ -202,14 +202,14 @@ private TermsQueryBuilder(String fieldName, Supplier> supplier) { this.supplier = supplier; } - private TermsQueryBuilder(String fieldName, Iterable values, String rewrite_override) { + private TermsQueryBuilder(String fieldName, Iterable values, String rewriteOverride) { this(fieldName, values); - this.rewrite_override = rewrite_override; + this.rewriteOverride = rewriteOverride; } - private TermsQueryBuilder(String fieldName, Supplier> supplier, String rewrite_override) { + private TermsQueryBuilder(String fieldName, Supplier> supplier, String rewriteOverride) { this(fieldName, supplier); - this.rewrite_override = rewrite_override; + this.rewriteOverride = rewriteOverride; } /** @@ -221,8 +221,8 @@ public TermsQueryBuilder(StreamInput in) throws IOException { termsLookup = in.readOptionalWriteable(TermsLookup::new); values = (List) in.readGenericValue(); this.supplier = null; - if (in.getVersion().after(Version.V_2_16_0)) { - rewrite_override = in.readOptionalString(); + if (in.getVersion().after(Version.V_2_17_0)) { + rewriteOverride = in.readOptionalString(); } } @@ -234,8 +234,8 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(fieldName); out.writeOptionalWriteable(termsLookup); out.writeGenericValue(values); - if (out.getVersion().after(Version.V_2_16_0)) { - out.writeOptionalString(rewrite_override); + if (out.getVersion().after(Version.V_2_17_0)) { + out.writeOptionalString(rewriteOverride); } } @@ -251,8 +251,8 @@ public TermsLookup termsLookup() { return this.termsLookup; } - public TermsQueryBuilder rewrite_override(String rewrite_override) { - this.rewrite_override = rewrite_override; + public TermsQueryBuilder rewriteOverride(String rewriteOverride) { + this.rewriteOverride = rewriteOverride; return this; } @@ -389,8 +389,8 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep builder.field(fieldName, convertBack(values)); } printBoostAndQueryName(builder); - if (rewrite_override != null) { - builder.field(REWRITE_OVERRIDE.getPreferredName(), rewrite_override); + if (rewriteOverride != null) { + builder.field(REWRITE_OVERRIDE.getPreferredName(), rewriteOverride); } builder.endObject(); } @@ -400,7 +400,7 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc List values = null; TermsLookup termsLookup = null; - String rewrite_override = null; + String rewriteOverride = null; String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; @@ -441,7 +441,7 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc } else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { queryName = parser.text(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { - rewrite_override = parser.textOrNull(); + rewriteOverride = parser.textOrNull(); } else { throw new ParsingException( parser.getTokenLocation(), @@ -466,7 +466,7 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc ); } - return new TermsQueryBuilder(fieldName, values, termsLookup).boost(boost).queryName(queryName).rewrite_override(rewrite_override); + return new TermsQueryBuilder(fieldName, values, termsLookup).boost(boost).queryName(queryName).rewriteOverride(rewriteOverride); } static List parseValues(XContentParser parser) throws IOException { @@ -509,12 +509,12 @@ protected Query doToQuery(QueryShardContext context) throws IOException { if (fieldType == null) { throw new IllegalStateException("Rewrite first"); } - QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( - rewrite_override, + QueryShardContext.RewriteOverride rewriteOverrideMethod = QueryParsers.parseRewriteOverride( + rewriteOverride, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); - return fieldType.termsQuery(values, rewriteOverride, context); + return fieldType.termsQuery(values, rewriteOverrideMethod, context); } private void fetch(TermsLookup termsLookup, Client client, ActionListener> actionListener) { @@ -532,7 +532,7 @@ private void fetch(TermsLookup termsLookup, Client client, ActionListener> supplier = new SetOnce<>(); queryRewriteContext.registerAsyncAction((client, listener) -> fetch(termsLookup, client, ActionListener.map(listener, list -> { supplier.set(list); return null; }))); - return new TermsQueryBuilder(this.fieldName, supplier::get, rewrite_override); + return new TermsQueryBuilder(this.fieldName, supplier::get, rewriteOverride); } if (values == null || values.isEmpty()) { diff --git a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java index 733111398cc70..0b376507b8f13 100644 --- a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java @@ -70,7 +70,7 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder Date: Mon, 19 Aug 2024 14:01:35 -0700 Subject: [PATCH 17/23] Fix prefix query Signed-off-by: Harsha Vamsi Kalluri --- .../org/opensearch/index/query/PrefixQueryBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java index 6e5963ad63034..bfa24ca096f10 100644 --- a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java @@ -241,13 +241,14 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws // This logic is correct for all field types, but by only applying it to constant // fields we also have the guarantee that it doesn't perform I/O, which is important // since rewrites might happen on a network thread. - QueryShardContext.RewriteOverride rewriteOverride = QueryParsers.parseRewriteOverride( + QueryShardContext.RewriteOverride rewriteOverrideMethod = QueryParsers.parseRewriteOverride( rewriteOverride, QueryShardContext.RewriteOverride.INDEX_OR_DOC_VALUES, LoggingDeprecationHandler.INSTANCE ); - Query query = fieldType.prefixQuery(value, null, rewriteOverride, caseInsensitive, context); // the rewrite method doesn't - // matter + Query query = fieldType.prefixQuery(value, null, rewriteOverrideMethod, caseInsensitive, context); // the rewrite method + // doesn't + // matter if (query instanceof MatchAllDocsQuery) { return new MatchAllQueryBuilder(); } else if (query instanceof MatchNoDocsQuery) { From 85e0db5731461e7b7ec5c57085946a277772be9d Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Tue, 20 Aug 2024 15:24:10 -0700 Subject: [PATCH 18/23] Separate rewrite tests Signed-off-by: Harsha Vamsi Kalluri --- .../test/search/340_doc_values_field.yml | 448 +++++++++++------- .../index/query/TermsQueryBuilder.java | 13 +- 2 files changed, 287 insertions(+), 174 deletions(-) diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml index c23584102b212..8709a2cac001c 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml @@ -82,32 +82,6 @@ - match: { hits.total: 2 } - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - terms: { - some_keyword: ["400", "5"], - rewrite_override: "index_only" - } - - - match: { hits.total: 2 } - - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - terms: { - some_keyword: ["400", "5"], - rewrite_override: "doc_values_only" - } - - - match: { hits.total: 2 } - - do: search: rest_total_hits_as_int: true @@ -121,34 +95,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - fuzzy: - some_keyword: { - value: "402", - rewrite_override: "index_only" - } - - - match: { hits.total: 1 } - - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - fuzzy: - some_keyword: { - value: "402", - rewrite_override: "doc_values_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -162,34 +108,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - regexp: - some_keyword: { - value: "40*", - rewrite_override: "index_only" - } - - - match: { hits.total: 1 } - - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - regexp: - some_keyword: { - value: "40*", - rewrite_override: "doc_values_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -203,34 +121,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - wildcard: - some_keyword: { - value: "ing*", - rewrite_override: "index_only" - } - - - match: { hits.total: 1 } - - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - wildcard: - some_keyword: { - value: "ing*", - rewrite_override: "doc_values_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -242,34 +132,6 @@ - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - prefix: - some_keyword: { - value: "ing", - rewrite_override: "index_only" - } - - - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } - - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - prefix: - some_keyword: { - value: "ing", - rewrite_override: "doc_values_only" - } - - - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } - - do: search: rest_total_hits_as_int: true @@ -283,37 +145,6 @@ - match: { hits.total: 2 } - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - range: { - "some_keyword": { - "lt": 500, - rewrite_override: "index_only" - - } } - - - match: { hits.total: 2 } - - - do: - search: - rest_total_hits_as_int: true - index: test-iodvq - body: - query: - range: { - "some_keyword": { - "lt": 500, - rewrite_override: "doc_values_only" - - } } - - - match: { hits.total: 2 } - - - do: search: rest_total_hits_as_int: true @@ -2088,3 +1919,282 @@ } - match: { hits.total: 0 } + +--- +"search with rewrite_override": + - skip: + features: [ "headers" ] + version: " - 2.16.99" + reason: "rewrite_override parameter was added in 2.17.0" + - do: + indices.create: + index: test-rewrite + body: + mappings: + properties: + some_keyword: + type: keyword + index: true + doc_values: true + some_keyword_index: + type: keyword + index: true + doc_values: false + some_keyword_dv: + type: keyword + index: false + doc_values: true + + - do: + bulk: + index: test-rewrite + refresh: true + body: + - '{"index": {"_index": "test-rewrite", "_id": "1" }}' + - '{ "some_keyword": "ingesting some random keyword data", "some_keyword_index": "ingesting some random keyword data", "some_keyword_dv": "ingesting some random keyword data" }' + - '{ "index": { "_index": "test-rewrite", "_id": "2" }}' + - '{ "some_keyword": "400", "some_keyword_index": "400", "some_keyword_dv": "400" }' + - '{ "index": { "_index": "test-rewrite", "_id": "3" } }' + - '{ "some_keyword": "5", "some_keyword_index": "5", "some_keyword_dv": "5" }' + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + terms: + some_keyword: ["400", "5"] + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + terms: { + some_keyword_index: ["400", "5"], + rewrite_override: "index_only" + } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + terms: { + some_keyword_dv: ["400", "5"], + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + fuzzy: + some_keyword: { + value: "402" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + fuzzy: + some_keyword_index: { + value: "402", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + fuzzy: + some_keyword_dv: { + value: "402", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + regexp: + some_keyword: { + value: "40*" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + regexp: + some_keyword_index: { + value: "40*", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + regexp: + some_keyword_dv: { + value: "40*", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + wildcard: + some_keyword: { + value: "ing*" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + wildcard: + some_keyword_index: { + value: "ing*", + rewrite_override: "index_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + wildcard: + some_keyword_dv: { + value: "ing*", + rewrite_override: "doc_values_only" + } + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + prefix: + some_keyword: "ing" + + - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + prefix: + some_keyword_index: { + value: "ing", + rewrite_override: "index_only" + } + + - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + prefix: + some_keyword_dv: { + value: "ing", + rewrite_override: "doc_values_only" + } + + - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + range: { + "some_keyword": { + "lt": 500 + } } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + range: { + "some_keyword_index": { + "lt": 500, + rewrite_override: "index_only" + + } } + + - match: { hits.total: 2 } + + - do: + search: + rest_total_hits_as_int: true + index: test-rewrite + body: + query: + range: { + "some_keyword_dv": { + "lt": 500, + rewrite_override: "doc_values_only" + + } } + + - match: { hits.total: 2 } diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index f2ff416c059f8..cadc1acbf60ef 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -57,8 +57,8 @@ import org.opensearch.index.IndexSettings; import org.opensearch.index.mapper.ConstantFieldType; import org.opensearch.index.mapper.MappedFieldType; -import org.opensearch.index.query.support.QueryParsers; import org.opensearch.index.mapper.NumberFieldMapper; +import org.opensearch.index.query.support.QueryParsers; import org.opensearch.indices.TermsLookup; import java.io.IOException; @@ -250,7 +250,8 @@ private TermsQueryBuilder(String fieldName, Iterable values, String rewriteOv private TermsQueryBuilder(String fieldName, Supplier> supplier, String rewriteOverride) { this(fieldName, supplier); this.rewriteOverride = rewriteOverride; - + } + private TermsQueryBuilder(String fieldName, Supplier> supplier, ValueType valueType) { this(fieldName, supplier); this.valueType = valueType; @@ -497,7 +498,6 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc queryName = parser.text(); } else if (REWRITE_OVERRIDE.match(currentFieldName, parser.getDeprecationHandler())) { rewriteOverride = parser.textOrNull(); - } } else if (VALUE_TYPE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { valueTypeStr = parser.text(); } else { @@ -535,7 +535,10 @@ public static TermsQueryBuilder fromXContent(XContentParser parser) throws IOExc } } - return new TermsQueryBuilder(fieldName, values, termsLookup).boost(boost).queryName(queryName).valueType(valueType).rewriteOverride(rewriteOverride); + return new TermsQueryBuilder(fieldName, values, termsLookup).boost(boost) + .queryName(queryName) + .valueType(valueType) + .rewriteOverride(rewriteOverride); } static List parseValues(XContentParser parser) throws IOException { @@ -644,7 +647,7 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { supplier.set(list); return null; }))); - return new TermsQueryBuilder(this.fieldName, supplier::get, valueType, rewriteOverride); + return new TermsQueryBuilder(this.fieldName, supplier::get, valueType); } if (values == null || values.isEmpty()) { From f044fc60ff6bd761082d5648460cc4b801d28cc1 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Tue, 20 Aug 2024 16:47:49 -0700 Subject: [PATCH 19/23] Fix query rewrite for terms Signed-off-by: Harsha Vamsi Kalluri --- .../index/query/TermsQueryBuilder.java | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index cadc1acbf60ef..7e9dc59076d54 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -230,9 +230,10 @@ public TermsQueryBuilder(String fieldName, Iterable values) { this.supplier = null; } - private TermsQueryBuilder(String fieldName, Iterable values, ValueType valueType) { + private TermsQueryBuilder(String fieldName, Iterable values, ValueType valueType, String rewriteOverride) { this(fieldName, values); this.valueType = valueType; + this.rewriteOverride = rewriteOverride; } private TermsQueryBuilder(String fieldName, Supplier> supplier) { @@ -242,19 +243,10 @@ private TermsQueryBuilder(String fieldName, Supplier> supplier) { this.supplier = supplier; } - private TermsQueryBuilder(String fieldName, Iterable values, String rewriteOverride) { - this(fieldName, values); - this.rewriteOverride = rewriteOverride; - } - - private TermsQueryBuilder(String fieldName, Supplier> supplier, String rewriteOverride) { - this(fieldName, supplier); - this.rewriteOverride = rewriteOverride; - } - - private TermsQueryBuilder(String fieldName, Supplier> supplier, ValueType valueType) { + private TermsQueryBuilder(String fieldName, Supplier> supplier, ValueType valueType, String rewriteOverride) { this(fieldName, supplier); this.valueType = valueType; + this.rewriteOverride = rewriteOverride; } /** @@ -647,7 +639,7 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { supplier.set(list); return null; }))); - return new TermsQueryBuilder(this.fieldName, supplier::get, valueType); + return new TermsQueryBuilder(this.fieldName, supplier::get, valueType, rewriteOverride); } if (values == null || values.isEmpty()) { From 89ff5c83bc0a3ccc4ed0528fbb916fde9a1e47f3 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Tue, 20 Aug 2024 17:47:32 -0700 Subject: [PATCH 20/23] Remove tests from older section Signed-off-by: Harsha Vamsi Kalluri --- .../test/search/340_doc_values_field.yml | 168 ------------------ 1 file changed, 168 deletions(-) diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml index 8709a2cac001c..f97bcbcae00b5 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml @@ -668,19 +668,6 @@ - match: { hits.total: 2 } - - do: - search: - rest_total_hits_as_int: true - index: test-index - body: - query: - terms: { - some_keyword: ["400", "5"], - rewrite_override: "index_only" - } - - - match: { hits.total: 2 } - - do: search: rest_total_hits_as_int: true @@ -694,20 +681,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-index - body: - query: - fuzzy: - some_keyword: { - value: "402", - rewrite_override: "index_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -721,20 +694,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-index - body: - query: - regexp: - some_keyword: { - value: "40*", - rewrite_override: "index_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -748,20 +707,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-index - body: - query: - wildcard: - some_keyword: { - value: "ing*", - rewrite_override: "index_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -773,20 +718,6 @@ - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } - - do: - search: - rest_total_hits_as_int: true - index: test-index - body: - query: - prefix: - some_keyword: { - value: "ing", - rewrite_override: "index_only" - } - - - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } - - do: search: rest_total_hits_as_int: true @@ -800,21 +731,6 @@ - match: { hits.total: 2 } - - do: - search: - rest_total_hits_as_int: true - index: test-index - body: - query: - range: { - "some_keyword": { - "lt": 500, - rewrite_override: "index_only" - - } } - - - match: { hits.total: 2 } - - do: search: rest_total_hits_as_int: true @@ -1344,19 +1260,6 @@ - match: { hits.total: 2 } - - do: - search: - rest_total_hits_as_int: true - index: test-doc-values - body: - query: - terms: { - some_keyword: ["400", "5"], - rewrite_override: "doc_values_only" - } - - - match: { hits.total: 2 } - - do: search: rest_total_hits_as_int: true @@ -1370,20 +1273,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-doc-values - body: - query: - fuzzy: - some_keyword: { - value: "402", - rewrite_override: "doc_values_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -1397,20 +1286,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-doc-values - body: - query: - regexp: - some_keyword: { - value: "40*", - rewrite_override: "doc_values_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -1424,20 +1299,6 @@ - match: { hits.total: 1 } - - do: - search: - rest_total_hits_as_int: true - index: test-doc-values - body: - query: - wildcard: - some_keyword: { - value: "ing*", - rewrite_override: "doc_values_only" - } - - - match: { hits.total: 1 } - - do: search: rest_total_hits_as_int: true @@ -1449,20 +1310,6 @@ - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } - - do: - search: - rest_total_hits_as_int: true - index: test-doc-values - body: - query: - prefix: - some_keyword: { - value: "ing", - rewrite_override: "doc_values_only" - } - - - match: { hits.hits.0._source.some_keyword: "ingesting some random keyword data" } - - do: search: rest_total_hits_as_int: true @@ -1476,21 +1323,6 @@ - match: { hits.total: 2 } - - do: - search: - rest_total_hits_as_int: true - index: test-doc-values - body: - query: - range: { - "some_keyword": { - "lt": 500, - rewrite_override: "doc_values_only" - - } } - - - match: { hits.total: 2 } - - do: search: rest_total_hits_as_int: true From ce3eb14a491615b5c58519d5e7d6f150ba9b4130 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Wed, 21 Aug 2024 09:23:55 -0700 Subject: [PATCH 21/23] Update version to 3.0 Signed-off-by: Harsha Vamsi Kalluri --- .../java/org/opensearch/index/query/FuzzyQueryBuilder.java | 4 ++-- .../java/org/opensearch/index/query/PrefixQueryBuilder.java | 4 ++-- .../java/org/opensearch/index/query/RangeQueryBuilder.java | 4 ++-- .../java/org/opensearch/index/query/RegexpQueryBuilder.java | 4 ++-- .../java/org/opensearch/index/query/TermsQueryBuilder.java | 4 ++-- .../java/org/opensearch/index/query/WildcardQueryBuilder.java | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java index 3f4d3dd974967..e420784f558c0 100644 --- a/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java @@ -186,7 +186,7 @@ public FuzzyQueryBuilder(StreamInput in) throws IOException { maxExpansions = in.readVInt(); transpositions = in.readBoolean(); rewrite = in.readOptionalString(); - if (in.getVersion().onOrAfter(Version.V_2_17_0)) { + if (in.getVersion().onOrAfter(Version.V_3_0_0)) { rewriteOverride = in.readOptionalString(); } } @@ -200,7 +200,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeVInt(this.maxExpansions); out.writeBoolean(this.transpositions); out.writeOptionalString(this.rewrite); - if (out.getVersion().onOrAfter(Version.V_2_17_0)) { + if (out.getVersion().onOrAfter(Version.V_3_0_0)) { out.writeOptionalString(rewriteOverride); } } diff --git a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java index bfa24ca096f10..668ed0283b21a 100644 --- a/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/PrefixQueryBuilder.java @@ -103,7 +103,7 @@ public PrefixQueryBuilder(StreamInput in) throws IOException { value = in.readString(); rewrite = in.readOptionalString(); caseInsensitive = in.readBoolean(); - if (in.getVersion().onOrAfter(Version.V_2_17_0)) { + if (in.getVersion().onOrAfter(Version.V_3_0_0)) { rewriteOverride = in.readOptionalString(); } } @@ -114,7 +114,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(value); out.writeOptionalString(rewrite); out.writeBoolean(caseInsensitive); - if (out.getVersion().onOrAfter(Version.V_2_17_0)) { + if (out.getVersion().onOrAfter(Version.V_3_0_0)) { out.writeOptionalString(rewriteOverride); } } diff --git a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java index 7973c0eef97c5..a631ed351dde6 100644 --- a/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java @@ -122,7 +122,7 @@ public RangeQueryBuilder(StreamInput in) throws IOException { throw new IllegalArgumentException("[range] query does not support relation [" + relationString + "]"); } } - if (in.getVersion().after(Version.V_2_17_0)) { + if (in.getVersion().after(Version.V_3_0_0)) { rewriteOverride = in.readOptionalString(); } } @@ -145,7 +145,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { relationString = this.relation.getRelationName(); } out.writeOptionalString(relationString); - if (out.getVersion().after(Version.V_2_17_0)) { + if (out.getVersion().after(Version.V_3_0_0)) { out.writeOptionalString(rewriteOverride); } } diff --git a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java index 01fe387e00196..726e9477a9347 100644 --- a/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/RegexpQueryBuilder.java @@ -117,7 +117,7 @@ public RegexpQueryBuilder(StreamInput in) throws IOException { maxDeterminizedStates = in.readVInt(); rewrite = in.readOptionalString(); caseInsensitive = in.readBoolean(); - if (in.getVersion().after(Version.V_2_17_0)) { + if (in.getVersion().after(Version.V_3_0_0)) { rewriteOverride = in.readOptionalString(); } } @@ -130,7 +130,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeVInt(maxDeterminizedStates); out.writeOptionalString(rewrite); out.writeBoolean(caseInsensitive); - if (out.getVersion().after(Version.V_2_17_0)) { + if (out.getVersion().after(Version.V_3_0_0)) { out.writeOptionalString(rewriteOverride); } } diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index 7e9dc59076d54..6ffd1e43d01ea 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -258,7 +258,7 @@ public TermsQueryBuilder(StreamInput in) throws IOException { termsLookup = in.readOptionalWriteable(TermsLookup::new); values = (List) in.readGenericValue(); this.supplier = null; - if (in.getVersion().after(Version.V_2_17_0)) { + if (in.getVersion().after(Version.V_3_0_0)) { rewriteOverride = in.readOptionalString(); } if (in.getVersion().onOrAfter(Version.V_3_0_0)) { @@ -274,7 +274,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(fieldName); out.writeOptionalWriteable(termsLookup); out.writeGenericValue(values); - if (out.getVersion().after(Version.V_2_17_0)) { + if (out.getVersion().after(Version.V_3_0_0)) { out.writeOptionalString(rewriteOverride); } if (out.getVersion().onOrAfter(Version.V_3_0_0)) { diff --git a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java index 0b376507b8f13..8369b3d1f1b54 100644 --- a/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/WildcardQueryBuilder.java @@ -113,7 +113,7 @@ public WildcardQueryBuilder(StreamInput in) throws IOException { value = in.readString(); rewrite = in.readOptionalString(); caseInsensitive = in.readBoolean(); - if (in.getVersion().after(Version.V_2_17_0)) { + if (in.getVersion().after(Version.V_3_0_0)) { rewriteOverride = in.readOptionalString(); } } @@ -124,7 +124,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(value); out.writeOptionalString(rewrite); out.writeBoolean(caseInsensitive); - if (out.getVersion().after(Version.V_2_17_0)) { + if (out.getVersion().after(Version.V_3_0_0)) { out.writeOptionalString(rewriteOverride); } } From a5a9e57b9abdb29654dbe9f8d93544259af89519 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Wed, 21 Aug 2024 10:33:48 -0700 Subject: [PATCH 22/23] Update version in yml tests Signed-off-by: Harsha Vamsi Kalluri --- .../rest-api-spec/test/search/340_doc_values_field.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml index f97bcbcae00b5..6d3fade1e05d8 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml @@ -1756,7 +1756,7 @@ "search with rewrite_override": - skip: features: [ "headers" ] - version: " - 2.16.99" + version: " - 2.99.99" reason: "rewrite_override parameter was added in 2.17.0" - do: indices.create: From 20de4762aab382712a05a2177ec73908406c0287 Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Thu, 22 Aug 2024 13:08:25 -0400 Subject: [PATCH 23/23] Update version check Signed-off-by: Harsha Vamsi Kalluri --- .../java/org/opensearch/index/query/TermsQueryBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java index f5e585f0f1f57..65e60d76f253c 100644 --- a/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/TermsQueryBuilder.java @@ -258,7 +258,7 @@ public TermsQueryBuilder(StreamInput in) throws IOException { termsLookup = in.readOptionalWriteable(TermsLookup::new); values = (List) in.readGenericValue(); this.supplier = null; - if (in.getVersion().after(Version.V_3_0_0)) { + if (in.getVersion().onOrAfter(Version.V_3_0_0)) { rewriteOverride = in.readOptionalString(); } if (in.getVersion().onOrAfter(Version.V_2_17_0)) { @@ -274,7 +274,7 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(fieldName); out.writeOptionalWriteable(termsLookup); out.writeGenericValue(values); - if (out.getVersion().after(Version.V_3_0_0)) { + if (out.getVersion().onOrAfter(Version.V_3_0_0)) { out.writeOptionalString(rewriteOverride); } if (out.getVersion().onOrAfter(Version.V_2_17_0)) {