瀏覽代碼

[Rest Api Compatibility] Types for Percolate Query Api (#74698)

Previously removed in #46985. The yaml test is included in this PR, but
will be removed once #74689 is merged.

relates #54160
relates main meta issue #51816
Przemyslaw Gomulka 4 年之前
父節點
當前提交
603ebf7b7f

+ 25 - 0
modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java

@@ -42,6 +42,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.logging.DeprecationLogger;
 import org.elasticsearch.common.xcontent.ConstructingObjectParser;
 import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
 import org.elasticsearch.common.xcontent.NamedXContentRegistry;
@@ -51,10 +52,12 @@ import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentHelper;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.core.RestApiVersion;
 import org.elasticsearch.index.fielddata.IndexFieldData;
 import org.elasticsearch.index.fielddata.IndexFieldDataCache;
 import org.elasticsearch.index.mapper.LuceneDocument;
 import org.elasticsearch.index.mapper.MappedFieldType;
+import org.elasticsearch.index.mapper.MapperService;
 import org.elasticsearch.index.mapper.ParsedDocument;
 import org.elasticsearch.index.mapper.SourceToParse;
 import org.elasticsearch.index.query.AbstractQueryBuilder;
@@ -74,19 +77,30 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.function.BiConsumer;
 import java.util.function.Supplier;
 
 import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
 import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
+import static org.elasticsearch.core.RestApiVersion.equalTo;
 import static org.elasticsearch.search.SearchService.ALLOW_EXPENSIVE_QUERIES;
 
 public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBuilder> {
+    private static final DeprecationLogger deprecationLogger =  DeprecationLogger.getLogger(ParseField.class);
+    static final String DOCUMENT_TYPE_DEPRECATION_MESSAGE = "[types removal] Types are deprecated in [percolate] queries. " +
+        "The [document_type] should no longer be specified.";
+    static final String TYPE_DEPRECATION_MESSAGE = "[types removal] Types are deprecated in [percolate] queries. " +
+        "The [type] of the indexed document should no longer be specified.";
+
+
     public static final String NAME = "percolate";
 
     static final ParseField DOCUMENT_FIELD = new ParseField("document");
     static final ParseField DOCUMENTS_FIELD = new ParseField("documents");
     private static final ParseField NAME_FIELD = new ParseField("name");
     private static final ParseField QUERY_FIELD = new ParseField("field");
+    private static final ParseField DOCUMENT_TYPE_FIELD = new ParseField("document_type");
+    private static final ParseField INDEXED_DOCUMENT_FIELD_TYPE = new ParseField("type");
     private static final ParseField INDEXED_DOCUMENT_FIELD_INDEX = new ParseField("index");
     private static final ParseField INDEXED_DOCUMENT_FIELD_ID = new ParseField("id");
     private static final ParseField INDEXED_DOCUMENT_FIELD_ROUTING = new ParseField("routing");
@@ -287,6 +301,9 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
             if (indexedDocumentIndex != null) {
                 builder.field(INDEXED_DOCUMENT_FIELD_INDEX.getPreferredName(), indexedDocumentIndex);
             }
+            if (builder.getRestApiVersion() == RestApiVersion.V_7) {
+                builder.field(INDEXED_DOCUMENT_FIELD_TYPE.getPreferredName(), MapperService.SINGLE_MAPPING_NAME);
+            }
             if (indexedDocumentId != null) {
                 builder.field(INDEXED_DOCUMENT_FIELD_ID.getPreferredName(), indexedDocumentId);
             }
@@ -338,6 +355,14 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
             DOCUMENTS_FIELD.getPreferredName(), INDEXED_DOCUMENT_FIELD_ID.getPreferredName());
         PARSER.declareExclusiveFieldSet(DOCUMENT_FIELD.getPreferredName(),
             DOCUMENTS_FIELD.getPreferredName(), INDEXED_DOCUMENT_FIELD_ID.getPreferredName());
+        PARSER.declareString(deprecateAndIgnoreType("percolate_with_type", TYPE_DEPRECATION_MESSAGE),
+            INDEXED_DOCUMENT_FIELD_TYPE.forRestApiVersion(equalTo(RestApiVersion.V_7)));
+        PARSER.declareString(deprecateAndIgnoreType("percolate_with_document_type", DOCUMENT_TYPE_DEPRECATION_MESSAGE),
+            DOCUMENT_TYPE_FIELD.forRestApiVersion(equalTo(RestApiVersion.V_7)));
+    }
+
+    private static BiConsumer<PercolateQueryBuilder, String> deprecateAndIgnoreType(String key, String message) {
+        return (target, type) -> deprecationLogger.compatibleApiWarning(key, message);
     }
 
     private static BytesReference parseDocument(XContentParser parser) throws IOException {

+ 28 - 0
modules/percolator/src/test/java/org/elasticsearch/percolator/PercolateQueryBuilderTests.java

@@ -22,7 +22,10 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput;
 import org.elasticsearch.common.lucene.uid.Versions;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.common.xcontent.json.JsonXContent;
+import org.elasticsearch.core.RestApiVersion;
 import org.elasticsearch.index.get.GetResult;
 import org.elasticsearch.index.mapper.MapperService;
 import org.elasticsearch.index.query.QueryBuilder;
@@ -346,4 +349,29 @@ public class PercolateQueryBuilderTests extends AbstractQueryTestCase<PercolateQ
         assertEquals("[percolate] queries cannot be executed when 'search.allow_expensive_queries' is set to false.",
                 e.getMessage());
     }
+
+    public void testFromJsonWithDocumentType() throws IOException {
+        SearchExecutionContext searchExecutionContext = createSearchExecutionContext();
+        String queryAsString = "{\"percolate\" : { \"document\": {}, \"document_type\":\"" + docType  + "\", \"field\":\"" +
+            queryField + "\"}}";
+        XContentParser parser = createParserWithCompatibilityFor(JsonXContent.jsonXContent, queryAsString, RestApiVersion.V_7);
+        QueryBuilder queryBuilder = parseQuery(parser);
+        queryBuilder.toQuery(searchExecutionContext);
+        assertWarnings(PercolateQueryBuilder.DOCUMENT_TYPE_DEPRECATION_MESSAGE);
+    }
+
+    public void testFromJsonWithType() throws IOException {
+        indexedDocumentIndex = randomAlphaOfLength(4);
+        indexedDocumentId = randomAlphaOfLength(4);
+        indexedDocumentVersion = Versions.MATCH_ANY;
+        documentSource = Collections.singletonList(randomSource(new HashSet<>()));
+        SearchExecutionContext searchExecutionContext = createSearchExecutionContext();
+
+        String  queryAsString =  "{\"percolate\" : { \"index\": \"" + indexedDocumentIndex +
+            "\", \"type\": \"_doc\", \"id\": \"" + indexedDocumentId + "\", \"field\":\"" + queryField + "\"}}";
+        XContentParser parser = createParserWithCompatibilityFor(JsonXContent.jsonXContent, queryAsString, RestApiVersion.V_7);
+         QueryBuilder queryBuilder = parseQuery(parser);
+        rewriteAndFetch(queryBuilder, searchExecutionContext).toQuery(searchExecutionContext);
+        assertWarnings(PercolateQueryBuilder.TYPE_DEPRECATION_MESSAGE);
+    }
 }

+ 150 - 0
modules/percolator/src/yamlRestCompatTest/resources/rest-api-spec/test/v7compat/11_basic_with_types.yml

@@ -0,0 +1,150 @@
+---
+setup:
+  - skip:
+      version: "9.0.0 - "
+      reason: "compatible from 8.x to 7.x"
+      features:
+        - "headers"
+        - "warnings"
+        - "allowed_warnings_regex"
+---
+"Test percolator basics via rest":
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      indices.create:
+        include_type_name: true
+        index: queries_index
+        body:
+          mappings:
+            queries_type:
+              properties:
+                query:
+                  type: percolator
+                foo:
+                  type: keyword
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      indices.create:
+        include_type_name: true
+        index: documents_index
+        body:
+          mappings:
+            documents_type:
+              properties:
+                foo:
+                  type: keyword
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      index:
+        index: queries_index
+        type: queries_type
+        id:   test_percolator
+        body:
+          query:
+            match_all: {}
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      index:
+        index: documents_index
+        type: documents_type
+        id: some_id
+        body:
+          foo: bar
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      indices.refresh: {}
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      search:
+        rest_total_hits_as_int: true
+        body:
+          - query:
+              percolate:
+                field: query
+                document:
+                  document_type: queries_type
+                  foo: bar
+  - match:  { hits.total:     1  }
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      msearch:
+        rest_total_hits_as_int: true
+        body:
+          - index: queries_index
+          - query:
+              percolate:
+                field: query
+                document_type: queries_type
+                document:
+                  foo: bar
+  - match:  { responses.0.hits.total:     1  }
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      search:
+        rest_total_hits_as_int: true
+        body:
+          - query:
+              percolate:
+                field: query
+                index: documents_index
+                type: documents_type
+                id: some_id
+  - match:  { hits.total:     1  }
+
+  - do:
+      headers:
+        Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+        Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+      allowed_warnings_regex:
+        - "\\[types removal\\].*"
+      msearch:
+        rest_total_hits_as_int: true
+        body:
+          - index: queries_index
+          - query:
+              percolate:
+                field: query
+                index: documents_index
+                type: documents_type
+                id: some_id
+  - match:  { responses.0.hits.total:     1  }

+ 4 - 2
server/src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java

@@ -205,7 +205,8 @@ public class MultiSearchRequest extends ActionRequest implements CompositeIndice
             // now parse the action
             if (nextMarker - from > 0) {
                 try (InputStream stream = data.slice(from, nextMarker - from).streamInput();
-                     XContentParser parser = xContent.createParser(registry, LoggingDeprecationHandler.INSTANCE, stream)) {
+                     XContentParser parser = xContent
+                         .createParserForCompatibility(registry, LoggingDeprecationHandler.INSTANCE, stream, restApiVersion)) {
                     Map<String, Object> source = parser.map();
                     Object expandWildcards = null;
                     Object ignoreUnavailable = null;
@@ -260,7 +261,8 @@ public class MultiSearchRequest extends ActionRequest implements CompositeIndice
             }
             BytesReference bytes = data.slice(from, nextMarker - from);
             try (InputStream stream = bytes.streamInput();
-                 XContentParser parser = xContent.createParser(registry, LoggingDeprecationHandler.INSTANCE, stream)) {
+                 XContentParser parser = xContent
+                     .createParserForCompatibility(registry, LoggingDeprecationHandler.INSTANCE, stream, restApiVersion)) {
                 consumer.accept(searchRequest, parser);
             }
             // move pointers