Skip to content

Commit aaeb47d

Browse files
HLRC for _mtermvectors (#35266)
relates to #27205
1 parent b205713 commit aaeb47d

File tree

13 files changed

+522
-8
lines changed

13 files changed

+522
-8
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.elasticsearch.action.support.WriteRequest;
5151
import org.elasticsearch.action.update.UpdateRequest;
5252
import org.elasticsearch.client.core.CountRequest;
53+
import org.elasticsearch.client.core.MultiTermVectorsRequest;
5354
import org.elasticsearch.client.core.TermVectorsRequest;
5455
import org.elasticsearch.client.security.RefreshPolicy;
5556
import org.elasticsearch.cluster.health.ClusterHealthStatus;
@@ -626,6 +627,13 @@ static Request termVectors(TermVectorsRequest tvrequest) throws IOException {
626627
return request;
627628
}
628629

630+
static Request mtermVectors(MultiTermVectorsRequest mtvrequest) throws IOException {
631+
String endpoint = "_mtermvectors";
632+
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
633+
request.setEntity(createEntity(mtvrequest, REQUEST_BODY_CONTENT_TYPE));
634+
return request;
635+
}
636+
629637
static Request getScript(GetStoredScriptRequest getStoredScriptRequest) {
630638
String endpoint = new EndpointBuilder().addPathPartAsIs("_scripts").addPathPart(getStoredScriptRequest.id()).build();
631639
Request request = new Request(HttpGet.METHOD_NAME, endpoint);

client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
import org.elasticsearch.client.core.CountResponse;
6161
import org.elasticsearch.client.core.TermVectorsResponse;
6262
import org.elasticsearch.client.core.TermVectorsRequest;
63+
import org.elasticsearch.client.core.MultiTermVectorsRequest;
64+
import org.elasticsearch.client.core.MultiTermVectorsResponse;
6365
import org.elasticsearch.client.tasks.TaskSubmissionResponse;
6466
import org.elasticsearch.common.CheckedConsumer;
6567
import org.elasticsearch.common.CheckedFunction;
@@ -1158,6 +1160,37 @@ public final void termvectorsAsync(TermVectorsRequest request, RequestOptions op
11581160
}
11591161

11601162

1163+
/**
1164+
* Calls the Multi Term Vectors API
1165+
*
1166+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-multi-termvectors.html">Multi Term Vectors API
1167+
* on elastic.co</a>
1168+
*
1169+
* @param request the request
1170+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
1171+
*/
1172+
public final MultiTermVectorsResponse mtermvectors(MultiTermVectorsRequest request, RequestOptions options) throws IOException {
1173+
return performRequestAndParseEntity(
1174+
request, RequestConverters::mtermVectors, options, MultiTermVectorsResponse::fromXContent, emptySet());
1175+
}
1176+
1177+
1178+
/**
1179+
* Asynchronously calls the Multi Term Vectors API
1180+
*
1181+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-multi-termvectors.html">Multi Term Vectors API
1182+
* on elastic.co</a>
1183+
* @param request the request
1184+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
1185+
* @param listener the listener to be notified upon request completion
1186+
*/
1187+
public final void mtermvectorsAsync(MultiTermVectorsRequest request, RequestOptions options,
1188+
ActionListener<MultiTermVectorsResponse> listener) {
1189+
performRequestAsyncAndParseEntity(
1190+
request, RequestConverters::mtermVectors, options, MultiTermVectorsResponse::fromXContent, listener, emptySet());
1191+
}
1192+
1193+
11611194
/**
11621195
* Executes a request using the Ranking Evaluation API.
11631196
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-rank-eval.html">Ranking Evaluation API
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.core;
21+
22+
import org.elasticsearch.client.Validatable;
23+
import org.elasticsearch.common.xcontent.ToXContentObject;
24+
import org.elasticsearch.common.xcontent.XContentBuilder;
25+
26+
import java.io.IOException;
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
30+
import static org.elasticsearch.client.core.TermVectorsRequest.createFromTemplate;
31+
32+
public class MultiTermVectorsRequest implements ToXContentObject, Validatable {
33+
34+
private List<TermVectorsRequest> requests = new ArrayList<>();
35+
36+
/**
37+
* Constructs an empty MultiTermVectorsRequest
38+
* After that use {@code add} method to add individual {@code TermVectorsRequest} to it.
39+
*/
40+
public MultiTermVectorsRequest() {};
41+
42+
/**
43+
* Constructs a MultiTermVectorsRequest from the given document ids
44+
* and a template {@code TermVectorsRequest}.
45+
* Used when individual requests share the same index, type and other settings.
46+
* @param ids - ids of documents for which term vectors are requested
47+
* @param template - a template {@code TermVectorsRequest} that allows to set all
48+
* settings only once for all requests.
49+
*/
50+
public MultiTermVectorsRequest(String[] ids, TermVectorsRequest template) {
51+
for (String id : ids) {
52+
TermVectorsRequest request = createFromTemplate(template, id);
53+
requests.add(request);
54+
}
55+
}
56+
57+
/**
58+
* Adds another {@code TermVectorsRequest} to this {@code MultiTermVectorsRequest}
59+
* @param request - {@code TermVectorsRequest} to add
60+
*/
61+
public void add(TermVectorsRequest request) {
62+
requests.add(request);
63+
}
64+
65+
@Override
66+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
67+
builder.startObject();
68+
builder.startArray("docs");
69+
for (TermVectorsRequest request : requests) {
70+
request.toXContent(builder, params);
71+
}
72+
builder.endArray();
73+
builder.endObject();
74+
return builder;
75+
}
76+
77+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.core;
21+
22+
23+
import org.elasticsearch.common.ParseField;
24+
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
25+
import org.elasticsearch.common.xcontent.XContentParser;
26+
27+
import java.util.List;
28+
import java.util.Objects;
29+
30+
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
31+
32+
public class MultiTermVectorsResponse {
33+
private final List<TermVectorsResponse> responses;
34+
35+
public MultiTermVectorsResponse(List<TermVectorsResponse> responses) {
36+
this.responses = responses;
37+
}
38+
39+
private static ConstructingObjectParser<MultiTermVectorsResponse, Void> PARSER =
40+
new ConstructingObjectParser<>("multi_term_vectors", true,
41+
args -> {
42+
// as the response comes from server, we are sure that args[0] will be a list of TermVectorsResponse
43+
@SuppressWarnings("unchecked") List<TermVectorsResponse> termVectorsResponsesList = (List<TermVectorsResponse>) args[0];
44+
return new MultiTermVectorsResponse(termVectorsResponsesList);
45+
}
46+
);
47+
48+
static {
49+
PARSER.declareObjectArray(constructorArg(), (p,c) -> TermVectorsResponse.fromXContent(p), new ParseField("docs"));
50+
}
51+
52+
public static MultiTermVectorsResponse fromXContent(XContentParser parser) {
53+
return PARSER.apply(parser, null);
54+
}
55+
56+
/**
57+
* Returns the list of {@code TermVectorsResponse} for this {@code MultiTermVectorsResponse}
58+
*/
59+
public List<TermVectorsResponse> getTermVectorsResponses() {
60+
return responses;
61+
}
62+
63+
64+
@Override
65+
public boolean equals(Object obj) {
66+
if (this == obj) return true;
67+
if (!(obj instanceof MultiTermVectorsResponse)) return false;
68+
MultiTermVectorsResponse other = (MultiTermVectorsResponse) obj;
69+
return Objects.equals(responses, other.responses);
70+
}
71+
72+
@Override
73+
public int hashCode() {
74+
return Objects.hash(responses);
75+
}
76+
77+
}

client/rest-high-level/src/main/java/org/elasticsearch/client/core/TermVectorsRequest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,29 @@ public TermVectorsRequest(String index, String type, XContentBuilder docBuilder)
7272
this.docBuilder = docBuilder;
7373
}
7474

75+
76+
/**
77+
* Constructs a new TermVectorRequest from a template
78+
* using the provided document id
79+
* @param template - a term vector request served as a template
80+
* @param id - id of the requested document
81+
*/
82+
static TermVectorsRequest createFromTemplate(TermVectorsRequest template, String id) {
83+
TermVectorsRequest request = new TermVectorsRequest(template.getIndex(), template.getType(), id);
84+
request.realtime = template.getRealtime();
85+
request.requestPositions = template.requestPositions;
86+
request.requestPayloads = template.requestPayloads;
87+
request.requestOffsets = template.requestOffsets;
88+
request.requestFieldStatistics = template.requestFieldStatistics;
89+
request.requestTermStatistics = template.requestTermStatistics;
90+
if (template.routing != null) request.setRouting(template.getRouting());
91+
if (template.preference != null) request.setPreference(template.getPreference());
92+
if (template.fields != null) request.setFields(template.getFields());
93+
if (template.perFieldAnalyzer != null) request.setPerFieldAnalyzer(template.perFieldAnalyzer);
94+
if (template.filterSettings != null) request.setFilterSettings(template.filterSettings);
95+
return request;
96+
}
97+
7598
/**
7699
* Returns the index of the request
77100
*/
@@ -201,6 +224,9 @@ public boolean getRealtime() {
201224
@Override
202225
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
203226
builder.startObject();
227+
builder.field("_index", index);
228+
builder.field("_type", type);
229+
if (id != null) builder.field("_id", id);
204230
// set values only when different from defaults
205231
if (requestPositions == false) builder.field("positions", false);
206232
if (requestPayloads == false) builder.field("payloads", false);

client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
4545
import org.elasticsearch.action.update.UpdateRequest;
4646
import org.elasticsearch.action.update.UpdateResponse;
47+
import org.elasticsearch.client.core.MultiTermVectorsRequest;
48+
import org.elasticsearch.client.core.MultiTermVectorsResponse;
4749
import org.elasticsearch.client.core.TermVectorsRequest;
4850
import org.elasticsearch.client.core.TermVectorsResponse;
4951
import org.elasticsearch.common.Strings;
@@ -73,6 +75,7 @@
7375
import org.joda.time.format.DateTimeFormat;
7476

7577
import java.io.IOException;
78+
import java.util.ArrayList;
7679
import java.util.Collections;
7780
import java.util.List;
7881
import java.util.Map;
@@ -1183,4 +1186,69 @@ public void testTermvectorsWithNonExistentIndex() {
11831186
() -> execute(request, highLevelClient()::termvectors, highLevelClient()::termvectorsAsync));
11841187
assertEquals(RestStatus.NOT_FOUND, exception.status());
11851188
}
1189+
1190+
// Not entirely sure if _mtermvectors belongs to CRUD, and in the absence of a better place, will have it here
1191+
public void testMultiTermvectors() throws IOException {
1192+
final String sourceIndex = "index1";
1193+
{
1194+
// prepare : index docs
1195+
Settings settings = Settings.builder()
1196+
.put("number_of_shards", 1)
1197+
.put("number_of_replicas", 0)
1198+
.build();
1199+
String mappings = "\"_doc\":{\"properties\":{\"field\":{\"type\":\"text\"}}}";
1200+
createIndex(sourceIndex, settings, mappings);
1201+
assertEquals(
1202+
RestStatus.OK,
1203+
highLevelClient().bulk(
1204+
new BulkRequest()
1205+
.add(new IndexRequest(sourceIndex, "_doc", "1")
1206+
.source(Collections.singletonMap("field", "value1"), XContentType.JSON))
1207+
.add(new IndexRequest(sourceIndex, "_doc", "2")
1208+
.source(Collections.singletonMap("field", "value2"), XContentType.JSON))
1209+
.setRefreshPolicy(RefreshPolicy.IMMEDIATE),
1210+
RequestOptions.DEFAULT
1211+
).status()
1212+
);
1213+
}
1214+
{
1215+
// test _mtermvectors where MultiTermVectorsRequest is constructed with ids and a template
1216+
String[] expectedIds = {"1", "2"};
1217+
TermVectorsRequest tvRequestTemplate = new TermVectorsRequest(sourceIndex, "_doc");
1218+
tvRequestTemplate.setFields("field");
1219+
MultiTermVectorsRequest mtvRequest = new MultiTermVectorsRequest(expectedIds, tvRequestTemplate);
1220+
1221+
MultiTermVectorsResponse mtvResponse =
1222+
execute(mtvRequest, highLevelClient()::mtermvectors, highLevelClient()::mtermvectorsAsync);
1223+
1224+
List<String> ids = new ArrayList<>();
1225+
for (TermVectorsResponse tvResponse: mtvResponse.getTermVectorsResponses()) {
1226+
assertThat(tvResponse.getIndex(), equalTo(sourceIndex));
1227+
assertTrue(tvResponse.getFound());
1228+
ids.add(tvResponse.getId());
1229+
}
1230+
assertArrayEquals(expectedIds, ids.toArray());
1231+
}
1232+
1233+
{
1234+
// test _mtermvectors where MultiTermVectorsRequest constructed with adding each separate request
1235+
MultiTermVectorsRequest mtvRequest = new MultiTermVectorsRequest();
1236+
TermVectorsRequest tvRequest1 = new TermVectorsRequest(sourceIndex, "_doc", "1");
1237+
tvRequest1.setFields("field");
1238+
mtvRequest.add(tvRequest1);
1239+
TermVectorsRequest tvRequest2 = new TermVectorsRequest(sourceIndex, "_doc");
1240+
XContentBuilder docBuilder = XContentFactory.jsonBuilder();
1241+
docBuilder.startObject().field("field", "valuex").endObject();
1242+
tvRequest2.setDoc(docBuilder);
1243+
mtvRequest.add(tvRequest2);
1244+
1245+
MultiTermVectorsResponse mtvResponse =
1246+
execute(mtvRequest, highLevelClient()::mtermvectors, highLevelClient()::mtermvectorsAsync);
1247+
for (TermVectorsResponse tvResponse: mtvResponse.getTermVectorsResponses()) {
1248+
assertThat(tvResponse.getIndex(), equalTo(sourceIndex));
1249+
assertTrue(tvResponse.getFound());
1250+
}
1251+
}
1252+
1253+
}
11861254
}

client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import org.elasticsearch.action.support.master.MasterNodeReadRequest;
5454
import org.elasticsearch.action.support.master.MasterNodeRequest;
5555
import org.elasticsearch.action.support.replication.ReplicationRequest;
56+
import org.elasticsearch.client.core.MultiTermVectorsRequest;
5657
import org.elasticsearch.client.core.TermVectorsRequest;
5758
import org.elasticsearch.action.update.UpdateRequest;
5859
import org.elasticsearch.client.RequestConverters.EndpointBuilder;
@@ -1303,6 +1304,26 @@ public void testTermVectors() throws IOException {
13031304
assertToXContentBody(tvRequest, request.getEntity());
13041305
}
13051306

1307+
public void testMultiTermVectors() throws IOException {
1308+
MultiTermVectorsRequest mtvRequest = new MultiTermVectorsRequest();
1309+
1310+
int numberOfRequests = randomIntBetween(0, 5);
1311+
for (int i = 0; i < numberOfRequests; i++) {
1312+
String index = randomAlphaOfLengthBetween(3, 10);
1313+
String type = randomAlphaOfLengthBetween(3, 10);
1314+
String id = randomAlphaOfLengthBetween(3, 10);
1315+
TermVectorsRequest tvRequest = new TermVectorsRequest(index, type, id);
1316+
String[] fields = generateRandomStringArray(10, 5, false, false);
1317+
tvRequest.setFields(fields);
1318+
mtvRequest.add(tvRequest);
1319+
}
1320+
1321+
Request request = RequestConverters.mtermVectors(mtvRequest);
1322+
assertEquals(HttpGet.METHOD_NAME, request.getMethod());
1323+
assertEquals("_mtermvectors", request.getEndpoint());
1324+
assertToXContentBody(mtvRequest, request.getEntity());
1325+
}
1326+
13061327
public void testFieldCaps() {
13071328
// Create a random request.
13081329
String[] indices = randomIndicesNames(0, 5);

client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,6 @@ public void testApiNamingConventions() throws Exception {
674674
"indices.exists_type",
675675
"indices.get_upgrade",
676676
"indices.put_alias",
677-
"mtermvectors",
678677
"render_search_template",
679678
"scripts_painless_execute"
680679
};

0 commit comments

Comments
 (0)