From b61b3f043b4629ea8a95be758c254ced2b38724b Mon Sep 17 00:00:00 2001 From: Mayya Sharipova Date: Mon, 19 Nov 2018 12:24:31 -0500 Subject: [PATCH] HLRC for _mtermvectors (#35266) relates to #27205 --- .../client/RequestConverters.java | 8 ++ .../client/RestHighLevelClient.java | 33 ++++++++ .../client/core/MultiTermVectorsRequest.java | 77 +++++++++++++++++++ .../client/core/MultiTermVectorsResponse.java | 77 +++++++++++++++++++ .../client/core/TermVectorsRequest.java | 26 +++++++ .../java/org/elasticsearch/client/CrudIT.java | 68 ++++++++++++++++ .../client/RequestConvertersTests.java | 21 +++++ .../client/RestHighLevelClientTests.java | 1 - .../core/MultiTermVectorsResponseTests.java | 67 ++++++++++++++++ .../client/core/TermVectorsResponseTests.java | 14 ++-- .../documentation/CRUDDocumentationIT.java | 76 ++++++++++++++++++ .../document/multi-term-vectors.asciidoc | 59 ++++++++++++++ .../high-level/supported-apis.asciidoc | 3 + 13 files changed, 522 insertions(+), 8 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/core/MultiTermVectorsRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/core/MultiTermVectorsResponse.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/core/MultiTermVectorsResponseTests.java create mode 100644 docs/java-rest/high-level/document/multi-term-vectors.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index 82bd825d51bca..910da82e43cd8 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -50,6 +50,7 @@ import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.client.core.CountRequest; +import org.elasticsearch.client.core.MultiTermVectorsRequest; import org.elasticsearch.client.core.TermVectorsRequest; import org.elasticsearch.client.security.RefreshPolicy; import org.elasticsearch.cluster.health.ClusterHealthStatus; @@ -634,6 +635,13 @@ static Request termVectors(TermVectorsRequest tvrequest) throws IOException { return request; } + static Request mtermVectors(MultiTermVectorsRequest mtvrequest) throws IOException { + String endpoint = "_mtermvectors"; + Request request = new Request(HttpGet.METHOD_NAME, endpoint); + request.setEntity(createEntity(mtvrequest, REQUEST_BODY_CONTENT_TYPE)); + return request; + } + static Request getScript(GetStoredScriptRequest getStoredScriptRequest) { String endpoint = new EndpointBuilder().addPathPartAsIs("_scripts").addPathPart(getStoredScriptRequest.id()).build(); Request request = new Request(HttpGet.METHOD_NAME, endpoint); diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java index 31a7e1319d960..e87fc4e328f3b 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java @@ -61,6 +61,8 @@ import org.elasticsearch.client.core.CountResponse; import org.elasticsearch.client.core.TermVectorsResponse; import org.elasticsearch.client.core.TermVectorsRequest; +import org.elasticsearch.client.core.MultiTermVectorsRequest; +import org.elasticsearch.client.core.MultiTermVectorsResponse; import org.elasticsearch.client.tasks.TaskSubmissionResponse; import org.elasticsearch.common.CheckedConsumer; import org.elasticsearch.common.CheckedFunction; @@ -1440,6 +1442,37 @@ public final void termvectorsAsync(TermVectorsRequest request, RequestOptions op } + /** + * Calls the Multi Term Vectors API + * + * See Multi Term Vectors API + * on elastic.co + * + * @param request the request + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + */ + public final MultiTermVectorsResponse mtermvectors(MultiTermVectorsRequest request, RequestOptions options) throws IOException { + return performRequestAndParseEntity( + request, RequestConverters::mtermVectors, options, MultiTermVectorsResponse::fromXContent, emptySet()); + } + + + /** + * Asynchronously calls the Multi Term Vectors API + * + * See Multi Term Vectors API + * on elastic.co + * @param request the request + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @param listener the listener to be notified upon request completion + */ + public final void mtermvectorsAsync(MultiTermVectorsRequest request, RequestOptions options, + ActionListener listener) { + performRequestAsyncAndParseEntity( + request, RequestConverters::mtermVectors, options, MultiTermVectorsResponse::fromXContent, listener, emptySet()); + } + + /** * Executes a request using the Ranking Evaluation API. * See Ranking Evaluation API diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/core/MultiTermVectorsRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/MultiTermVectorsRequest.java new file mode 100644 index 0000000000000..8ec5e79993cd8 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/MultiTermVectorsRequest.java @@ -0,0 +1,77 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.core; + +import org.elasticsearch.client.Validatable; +import org.elasticsearch.common.xcontent.ToXContentObject; +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.elasticsearch.client.core.TermVectorsRequest.createFromTemplate; + +public class MultiTermVectorsRequest implements ToXContentObject, Validatable { + + private List requests = new ArrayList<>(); + + /** + * Constructs an empty MultiTermVectorsRequest + * After that use {@code add} method to add individual {@code TermVectorsRequest} to it. + */ + public MultiTermVectorsRequest() {}; + + /** + * Constructs a MultiTermVectorsRequest from the given document ids + * and a template {@code TermVectorsRequest}. + * Used when individual requests share the same index, type and other settings. + * @param ids - ids of documents for which term vectors are requested + * @param template - a template {@code TermVectorsRequest} that allows to set all + * settings only once for all requests. + */ + public MultiTermVectorsRequest(String[] ids, TermVectorsRequest template) { + for (String id : ids) { + TermVectorsRequest request = createFromTemplate(template, id); + requests.add(request); + } + } + + /** + * Adds another {@code TermVectorsRequest} to this {@code MultiTermVectorsRequest} + * @param request - {@code TermVectorsRequest} to add + */ + public void add(TermVectorsRequest request) { + requests.add(request); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.startArray("docs"); + for (TermVectorsRequest request : requests) { + request.toXContent(builder, params); + } + builder.endArray(); + builder.endObject(); + return builder; + } + +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/core/MultiTermVectorsResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/MultiTermVectorsResponse.java new file mode 100644 index 0000000000000..0a2974a8aa166 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/MultiTermVectorsResponse.java @@ -0,0 +1,77 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.core; + + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.util.List; +import java.util.Objects; + +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; + +public class MultiTermVectorsResponse { + private final List responses; + + public MultiTermVectorsResponse(List responses) { + this.responses = responses; + } + + private static ConstructingObjectParser PARSER = + new ConstructingObjectParser<>("multi_term_vectors", true, + args -> { + // as the response comes from server, we are sure that args[0] will be a list of TermVectorsResponse + @SuppressWarnings("unchecked") List termVectorsResponsesList = (List) args[0]; + return new MultiTermVectorsResponse(termVectorsResponsesList); + } + ); + + static { + PARSER.declareObjectArray(constructorArg(), (p,c) -> TermVectorsResponse.fromXContent(p), new ParseField("docs")); + } + + public static MultiTermVectorsResponse fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); + } + + /** + * Returns the list of {@code TermVectorsResponse} for this {@code MultiTermVectorsResponse} + */ + public List getTermVectorsResponses() { + return responses; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof MultiTermVectorsResponse)) return false; + MultiTermVectorsResponse other = (MultiTermVectorsResponse) obj; + return Objects.equals(responses, other.responses); + } + + @Override + public int hashCode() { + return Objects.hash(responses); + } + +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/core/TermVectorsRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/TermVectorsRequest.java index 579ab52185198..ee5aaacbf0c20 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/core/TermVectorsRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/TermVectorsRequest.java @@ -72,6 +72,29 @@ public TermVectorsRequest(String index, String type, XContentBuilder docBuilder) this.docBuilder = docBuilder; } + + /** + * Constructs a new TermVectorRequest from a template + * using the provided document id + * @param template - a term vector request served as a template + * @param id - id of the requested document + */ + static TermVectorsRequest createFromTemplate(TermVectorsRequest template, String id) { + TermVectorsRequest request = new TermVectorsRequest(template.getIndex(), template.getType(), id); + request.realtime = template.getRealtime(); + request.requestPositions = template.requestPositions; + request.requestPayloads = template.requestPayloads; + request.requestOffsets = template.requestOffsets; + request.requestFieldStatistics = template.requestFieldStatistics; + request.requestTermStatistics = template.requestTermStatistics; + if (template.routing != null) request.setRouting(template.getRouting()); + if (template.preference != null) request.setPreference(template.getPreference()); + if (template.fields != null) request.setFields(template.getFields()); + if (template.perFieldAnalyzer != null) request.setPerFieldAnalyzer(template.perFieldAnalyzer); + if (template.filterSettings != null) request.setFilterSettings(template.filterSettings); + return request; + } + /** * Returns the index of the request */ @@ -201,6 +224,9 @@ public boolean getRealtime() { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); + builder.field("_index", index); + builder.field("_type", type); + if (id != null) builder.field("_id", id); // set values only when different from defaults if (requestPositions == false) builder.field("positions", false); if (requestPayloads == false) builder.field("payloads", false); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java index 2b9dfd672bb96..44e34a1041c0a 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java @@ -44,6 +44,8 @@ import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; +import org.elasticsearch.client.core.MultiTermVectorsRequest; +import org.elasticsearch.client.core.MultiTermVectorsResponse; import org.elasticsearch.client.core.TermVectorsRequest; import org.elasticsearch.client.core.TermVectorsResponse; import org.elasticsearch.common.Strings; @@ -73,6 +75,7 @@ import org.joda.time.format.DateTimeFormat; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -1250,4 +1253,69 @@ public void testTermvectorsWithNonExistentIndex() { () -> execute(request, highLevelClient()::termvectors, highLevelClient()::termvectorsAsync)); assertEquals(RestStatus.NOT_FOUND, exception.status()); } + + // Not entirely sure if _mtermvectors belongs to CRUD, and in the absence of a better place, will have it here + public void testMultiTermvectors() throws IOException { + final String sourceIndex = "index1"; + { + // prepare : index docs + Settings settings = Settings.builder() + .put("number_of_shards", 1) + .put("number_of_replicas", 0) + .build(); + String mappings = "\"_doc\":{\"properties\":{\"field\":{\"type\":\"text\"}}}"; + createIndex(sourceIndex, settings, mappings); + assertEquals( + RestStatus.OK, + highLevelClient().bulk( + new BulkRequest() + .add(new IndexRequest(sourceIndex, "_doc", "1") + .source(Collections.singletonMap("field", "value1"), XContentType.JSON)) + .add(new IndexRequest(sourceIndex, "_doc", "2") + .source(Collections.singletonMap("field", "value2"), XContentType.JSON)) + .setRefreshPolicy(RefreshPolicy.IMMEDIATE), + RequestOptions.DEFAULT + ).status() + ); + } + { + // test _mtermvectors where MultiTermVectorsRequest is constructed with ids and a template + String[] expectedIds = {"1", "2"}; + TermVectorsRequest tvRequestTemplate = new TermVectorsRequest(sourceIndex, "_doc"); + tvRequestTemplate.setFields("field"); + MultiTermVectorsRequest mtvRequest = new MultiTermVectorsRequest(expectedIds, tvRequestTemplate); + + MultiTermVectorsResponse mtvResponse = + execute(mtvRequest, highLevelClient()::mtermvectors, highLevelClient()::mtermvectorsAsync); + + List ids = new ArrayList<>(); + for (TermVectorsResponse tvResponse: mtvResponse.getTermVectorsResponses()) { + assertThat(tvResponse.getIndex(), equalTo(sourceIndex)); + assertTrue(tvResponse.getFound()); + ids.add(tvResponse.getId()); + } + assertArrayEquals(expectedIds, ids.toArray()); + } + + { + // test _mtermvectors where MultiTermVectorsRequest constructed with adding each separate request + MultiTermVectorsRequest mtvRequest = new MultiTermVectorsRequest(); + TermVectorsRequest tvRequest1 = new TermVectorsRequest(sourceIndex, "_doc", "1"); + tvRequest1.setFields("field"); + mtvRequest.add(tvRequest1); + TermVectorsRequest tvRequest2 = new TermVectorsRequest(sourceIndex, "_doc"); + XContentBuilder docBuilder = XContentFactory.jsonBuilder(); + docBuilder.startObject().field("field", "valuex").endObject(); + tvRequest2.setDoc(docBuilder); + mtvRequest.add(tvRequest2); + + MultiTermVectorsResponse mtvResponse = + execute(mtvRequest, highLevelClient()::mtermvectors, highLevelClient()::mtermvectorsAsync); + for (TermVectorsResponse tvResponse: mtvResponse.getTermVectorsResponses()) { + assertThat(tvResponse.getIndex(), equalTo(sourceIndex)); + assertTrue(tvResponse.getFound()); + } + } + + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index c2238f88454f5..78f0cd67fbc86 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -53,6 +53,7 @@ import org.elasticsearch.action.support.master.MasterNodeReadRequest; import org.elasticsearch.action.support.master.MasterNodeRequest; import org.elasticsearch.action.support.replication.ReplicationRequest; +import org.elasticsearch.client.core.MultiTermVectorsRequest; import org.elasticsearch.client.core.TermVectorsRequest; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.client.RequestConverters.EndpointBuilder; @@ -1315,6 +1316,26 @@ public void testTermVectors() throws IOException { assertToXContentBody(tvRequest, request.getEntity()); } + public void testMultiTermVectors() throws IOException { + MultiTermVectorsRequest mtvRequest = new MultiTermVectorsRequest(); + + int numberOfRequests = randomIntBetween(0, 5); + for (int i = 0; i < numberOfRequests; i++) { + String index = randomAlphaOfLengthBetween(3, 10); + String type = randomAlphaOfLengthBetween(3, 10); + String id = randomAlphaOfLengthBetween(3, 10); + TermVectorsRequest tvRequest = new TermVectorsRequest(index, type, id); + String[] fields = generateRandomStringArray(10, 5, false, false); + tvRequest.setFields(fields); + mtvRequest.add(tvRequest); + } + + Request request = RequestConverters.mtermVectors(mtvRequest); + assertEquals(HttpGet.METHOD_NAME, request.getMethod()); + assertEquals("_mtermvectors", request.getEndpoint()); + assertToXContentBody(mtvRequest, request.getEntity()); + } + public void testFieldCaps() { // Create a random request. String[] indices = randomIndicesNames(0, 5); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java index b433be3f5c513..e9f45b843f94d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java @@ -689,7 +689,6 @@ public void testApiNamingConventions() throws Exception { "indices.exists_type", "indices.get_upgrade", "indices.put_alias", - "mtermvectors", "render_search_template", "scripts_painless_execute" }; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/core/MultiTermVectorsResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/core/MultiTermVectorsResponseTests.java new file mode 100644 index 0000000000000..6db3139fbc569 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/core/MultiTermVectorsResponseTests.java @@ -0,0 +1,67 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.core; + +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester; + +public class MultiTermVectorsResponseTests extends ESTestCase { + + public void testFromXContent() throws IOException { + xContentTester( + this::createParser, + this::createTestInstance, + this::toXContent, + MultiTermVectorsResponse::fromXContent) + .supportsUnknownFields(true) + .randomFieldsExcludeFilter(field -> + field.endsWith("term_vectors") || field.endsWith("terms") || field.endsWith("tokens")) + .test(); + } + + private void toXContent(MultiTermVectorsResponse response, XContentBuilder builder) throws IOException { + builder.startObject(); + List termVectorsResponseList = response.getTermVectorsResponses(); + if (termVectorsResponseList != null) { + builder.startArray("docs"); + for (TermVectorsResponse tvr : termVectorsResponseList) { + TermVectorsResponseTests.toXContent(tvr, builder); + } + builder.endArray(); + } + builder.endObject(); + } + + protected MultiTermVectorsResponse createTestInstance() { + int numberOfResponses = randomIntBetween(0, 5); + List responses = new ArrayList<>(numberOfResponses); + for (int i = 0; i < numberOfResponses; i++) { + TermVectorsResponse tvResponse = TermVectorsResponseTests.createTestInstance(); + responses.add(tvResponse); + } + return new MultiTermVectorsResponse(responses); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/core/TermVectorsResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/core/TermVectorsResponseTests.java index 473bb34f4e660..714a7269a19d9 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/core/TermVectorsResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/core/TermVectorsResponseTests.java @@ -35,8 +35,8 @@ public class TermVectorsResponseTests extends ESTestCase { public void testFromXContent() throws IOException { xContentTester( this::createParser, - this::createTestInstance, - this::toXContent, + TermVectorsResponseTests::createTestInstance, + TermVectorsResponseTests::toXContent, TermVectorsResponse::fromXContent) .supportsUnknownFields(true) .randomFieldsExcludeFilter(field -> @@ -44,7 +44,7 @@ public void testFromXContent() throws IOException { .test(); } - private void toXContent(TermVectorsResponse response, XContentBuilder builder) throws IOException { + static void toXContent(TermVectorsResponse response, XContentBuilder builder) throws IOException { builder.startObject(); builder.field("_index", response.getIndex()); builder.field("_type", response.getType()); @@ -66,7 +66,7 @@ private void toXContent(TermVectorsResponse response, XContentBuilder builder) t builder.endObject(); } - private void toXContent(TermVectorsResponse.TermVector tv, XContentBuilder builder) throws IOException { + private static void toXContent(TermVectorsResponse.TermVector tv, XContentBuilder builder) throws IOException { builder.startObject(tv.getFieldName()); // build fields_statistics if (tv.getFieldStatistics() != null) { @@ -117,7 +117,7 @@ private void toXContent(TermVectorsResponse.TermVector tv, XContentBuilder build } - protected TermVectorsResponse createTestInstance() { + static TermVectorsResponse createTestInstance() { String index = randomAlphaOfLength(5); String type = randomAlphaOfLength(5); String id = String.valueOf(randomIntBetween(1,100)); @@ -148,7 +148,7 @@ protected TermVectorsResponse createTestInstance() { - private TermVectorsResponse.TermVector randomTermVector(String fieldName, boolean hasFieldStatistics, boolean hasTermStatistics, + private static TermVectorsResponse.TermVector randomTermVector(String fieldName, boolean hasFieldStatistics, boolean hasTermStatistics, boolean hasScores, boolean hasOffsets, boolean hasPositions, boolean hasPayloads) { TermVectorsResponse.TermVector.FieldStatistics fs = null; if (hasFieldStatistics) { @@ -171,7 +171,7 @@ private TermVectorsResponse.TermVector randomTermVector(String fieldName, boolea return tv; } - private TermVectorsResponse.TermVector.Term randomTerm(String termTxt, boolean hasTermStatistics, boolean hasScores, + private static TermVectorsResponse.TermVector.Term randomTerm(String termTxt, boolean hasTermStatistics, boolean hasScores, boolean hasOffsets, boolean hasPositions, boolean hasPayloads) { int termFreq = randomInt(10000); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CRUDDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CRUDDocumentationIT.java index 41036f900f411..b198d846e87b8 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CRUDDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CRUDDocumentationIT.java @@ -54,6 +54,8 @@ import org.elasticsearch.client.Response; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.RethrottleRequest; +import org.elasticsearch.client.core.MultiTermVectorsRequest; +import org.elasticsearch.client.core.MultiTermVectorsResponse; import org.elasticsearch.client.core.TermVectorsRequest; import org.elasticsearch.client.core.TermVectorsResponse; import org.elasticsearch.common.Strings; @@ -1667,6 +1669,80 @@ public void onFailure(Exception e) { } + + // Not entirely sure if _mtermvectors belongs to CRUD, and in the absence of a better place, will have it here + public void testMultiTermVectors() throws Exception { + RestHighLevelClient client = highLevelClient(); + CreateIndexRequest authorsRequest = new CreateIndexRequest("authors").mapping("_doc", "user", "type=text"); + CreateIndexResponse authorsResponse = client.indices().create(authorsRequest, RequestOptions.DEFAULT); + assertTrue(authorsResponse.isAcknowledged()); + client.index(new IndexRequest("index", "_doc", "1").source("user", "kimchy"), RequestOptions.DEFAULT); + client.index(new IndexRequest("index", "_doc", "2").source("user", "s1monw"), RequestOptions.DEFAULT); + Response refreshResponse = client().performRequest(new Request("POST", "/authors/_refresh")); + assertEquals(200, refreshResponse.getStatusLine().getStatusCode()); + + { + // tag::multi-term-vectors-request + MultiTermVectorsRequest request = new MultiTermVectorsRequest(); // <1> + TermVectorsRequest tvrequest1 = + new TermVectorsRequest("authors", "_doc", "1"); + tvrequest1.setFields("user"); + request.add(tvrequest1); // <2> + TermVectorsRequest tvrequest2 = + new TermVectorsRequest("authors", "_doc"); + XContentBuilder docBuilder = XContentFactory.jsonBuilder(); + docBuilder.startObject().field("user", "guest-user").endObject(); + tvrequest2.setDoc(docBuilder); + request.add(tvrequest2); // <3> + // end::multi-term-vectors-request + } + + // tag::multi-term-vectors-request-template + TermVectorsRequest tvrequestTemplate = + new TermVectorsRequest("authors", "_doc"); // <1> + tvrequestTemplate.setFields("user"); + String[] ids = {"1", "2"}; + MultiTermVectorsRequest request = + new MultiTermVectorsRequest(ids, tvrequestTemplate); // <2> + // end::multi-term-vectors-request-template + + // tag::multi-term-vectors-execute + MultiTermVectorsResponse response = + client.mtermvectors(request, RequestOptions.DEFAULT); + // end::multi-term-vectors-execute + + // tag::multi-term-vectors-response + List tvresponseList = + response.getTermVectorsResponses(); // <1> + if (tvresponseList != null) { + for (TermVectorsResponse tvresponse : tvresponseList) { + } + } + // end::multi-term-vectors-response + + ActionListener listener; + // tag::multi-term-vectors-execute-listener + listener = new ActionListener() { + @Override + public void onResponse(MultiTermVectorsResponse mtvResponse) { + // <1> + } + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::multi-term-vectors-execute-listener + CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + // tag::multi-term-vectors-execute-async + client.mtermvectorsAsync( + request, RequestOptions.DEFAULT, listener); // <1> + // end::multi-term-vectors-execute-async + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + + } + public void testMultiGet() throws Exception { RestHighLevelClient client = highLevelClient(); diff --git a/docs/java-rest/high-level/document/multi-term-vectors.asciidoc b/docs/java-rest/high-level/document/multi-term-vectors.asciidoc new file mode 100644 index 0000000000000..d2c4666130b2b --- /dev/null +++ b/docs/java-rest/high-level/document/multi-term-vectors.asciidoc @@ -0,0 +1,59 @@ +-- +:api: multi-term-vectors +:request: MultiTermVectorsRequest +:response: MultiTermVectorsResponse +:tvrequest: TermVectorsRequest +-- + +[id="{upid}-{api}"] +=== Multi Term Vectors API + +Multi Term Vectors API allows to get multiple term vectors at once. + +[id="{upid}-{api}-request"] +==== Multi Term Vectors Request +There are two ways to create a +{request}+. + +The first way is to create an empty +{request}+, and then add individual +<> to it. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request] +-------------------------------------------------- +<1> Create an empty +{request}+. +<2> Add the first +{tvrequest}+ to the +{request}+. +<3> Add the second +{tvrequest}+ for an artificial doc to the +{request}+. + + +The second way can be used when all term vectors requests share the same +arguments, such as index, type, and other settings. In this case, a template ++{tvrequest}+ can be created with all necessary settings set, and +this template request can be passed to +{request}+ along with all +documents' ids for which to execute these requests. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request-template] +-------------------------------------------------- +<1> Create a template +{tvrequest}+. +<2> Pass documents' ids and the template to the +{request}+. + + +include::../execution.asciidoc[] + + +[id="{upid}-{api}-response"] +==== Multi Term Vectors Response + ++{response}+ allows to get the list of term vectors responses, +each of which can be inspected as described in +<>. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-response] +-------------------------------------------------- +<1> Get a list of `TermVectorsResponse` + + diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index a265265fb16e6..dc93b8a48a780 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -24,6 +24,7 @@ Multi-document APIs:: * <<{upid}-update-by-query>> * <<{upid}-delete-by-query>> * <<{upid}-rethrottle>> +* <<{upid}-multi-term-vectors>> include::document/index.asciidoc[] include::document/get.asciidoc[] @@ -37,6 +38,8 @@ include::document/reindex.asciidoc[] include::document/update-by-query.asciidoc[] include::document/delete-by-query.asciidoc[] include::document/rethrottle.asciidoc[] +include::document/multi-term-vectors.asciidoc[] + == Search APIs