Add Get Source API to the HLRC (#51342)

Backport to 7.x branch of #50885.

Relates to #47678

Co-authored-by: Maxim <timonin.maksim@mail.ru>
This commit is contained in:
Martijn van Groningen 2020-01-23 13:16:20 +01:00 committed by GitHub
parent 8c8d0dbacc
commit 0a8d8d7ae3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 582 additions and 6 deletions

View File

@ -49,6 +49,7 @@ import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.GetSourceRequest;
import org.elasticsearch.client.core.MultiTermVectorsRequest;
import org.elasticsearch.client.core.TermVectorsRequest;
import org.elasticsearch.client.indices.AnalyzeRequest;
@ -281,6 +282,14 @@ final class RequestConverters {
}
static Request sourceExists(GetRequest getRequest) {
Params parameters = new Params();
parameters.withPreference(getRequest.preference());
parameters.withRouting(getRequest.routing());
parameters.withRefresh(getRequest.refresh());
parameters.withRealtime(getRequest.realtime());
parameters.withFetchSourceContext(getRequest.fetchSourceContext());
// Version params are not currently supported by the _source API so are not passed
String optionalType = getRequest.type();
String endpoint;
if (optionalType.equals(MapperService.SINGLE_MAPPING_NAME)) {
@ -289,12 +298,20 @@ final class RequestConverters {
endpoint = endpoint(getRequest.index(), optionalType, getRequest.id(), "_source");
}
Request request = new Request(HttpHead.METHOD_NAME, endpoint);
request.addParameters(parameters.asMap());
return request;
}
static Request getSource(GetSourceRequest getSourceRequest) {
Params parameters = new Params();
parameters.withPreference(getRequest.preference());
parameters.withRouting(getRequest.routing());
parameters.withRefresh(getRequest.refresh());
parameters.withRealtime(getRequest.realtime());
// Version params are not currently supported by the source exists API so are not passed
parameters.withPreference(getSourceRequest.preference());
parameters.withRouting(getSourceRequest.routing());
parameters.withRefresh(getSourceRequest.refresh());
parameters.withRealtime(getSourceRequest.realtime());
parameters.withFetchSourceContext(getSourceRequest.fetchSourceContext());
String endpoint = endpoint(getSourceRequest.index(), "_source", getSourceRequest.id());
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
request.addParameters(parameters.asMap());
return request;
}

View File

@ -56,6 +56,8 @@ import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.client.core.GetSourceRequest;
import org.elasticsearch.client.core.GetSourceResponse;
import org.elasticsearch.client.core.MainRequest;
import org.elasticsearch.client.core.MainResponse;
import org.elasticsearch.client.core.MultiTermVectorsRequest;
@ -860,6 +862,34 @@ public class RestHighLevelClient implements Closeable {
RestHighLevelClient::convertExistsResponse, listener, emptySet());
}
/**
* Retrieves the source field only of a document using GetSource API.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html#_source">Get Source API
* on elastic.co</a>
* @param getRequest the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response
*/
public GetSourceResponse getSource(GetSourceRequest getRequest, RequestOptions options) throws IOException {
return performRequestAndParseEntity(getRequest, RequestConverters::getSource, options,
GetSourceResponse::fromXContent, emptySet());
}
/**
* Asynchronously retrieves the source field only of a document using GetSource API.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html#_source">Get Source API
* on elastic.co</a>
* @param getRequest 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
* @return cancellable that may be used to cancel the request
*/
public final Cancellable getSourceAsync(GetSourceRequest getRequest, RequestOptions options,
ActionListener<GetSourceResponse> listener) {
return performRequestAsyncAndParseEntity(getRequest, RequestConverters::getSource, options,
GetSourceResponse::fromXContent, listener, emptySet());
}
/**
* Index a document using the Index API.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html">Index API on elastic.co</a>

View File

@ -0,0 +1,126 @@
/*
* 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 org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import java.io.IOException;
public final class GetSourceRequest implements Validatable, ToXContentObject {
private String routing;
private String preference;
private boolean refresh = false;
private boolean realtime = true;
private FetchSourceContext fetchSourceContext;
private String index;
private String id;
public GetSourceRequest(String index, String id) {
this.index = index;
this.id = id;
}
/**
* Controls the shard routing of the request. Using this value to hash the shard
* and not the id.
*/
public GetSourceRequest routing(String routing) {
if (routing != null && routing.length() == 0) {
this.routing = null;
} else {
this.routing = routing;
}
return this;
}
/**
* Sets the preference to execute the search. Defaults to randomize across shards. Can be set to
* {@code _local} to prefer local shards or a custom value, which guarantees that the same order
* will be used across different requests.
*/
public GetSourceRequest preference(String preference) {
this.preference = preference;
return this;
}
/**
* Should a refresh be executed before this get operation causing the operation to
* return the latest value. Note, heavy get should not set this to {@code true}. Defaults
* to {@code false}.
*/
public GetSourceRequest refresh(boolean refresh) {
this.refresh = refresh;
return this;
}
public GetSourceRequest realtime(boolean realtime) {
this.realtime = realtime;
return this;
}
/**
* Allows setting the {@link FetchSourceContext} for this request, controlling if and how _source should be returned.
* Note, the {@code fetchSource} field of the context must be set to {@code true}.
*/
public GetSourceRequest fetchSourceContext(FetchSourceContext context) {
this.fetchSourceContext = context;
return this;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return null;
}
public String index() {
return index;
}
public String id() {
return id;
}
public String routing() {
return routing;
}
public String preference() {
return preference;
}
public boolean refresh() {
return refresh;
}
public boolean realtime() {
return realtime;
}
public FetchSourceContext fetchSourceContext() {
return fetchSourceContext;
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.XContentParser;
import java.io.IOException;
import java.util.Map;
public final class GetSourceResponse {
private final Map<String, Object> source;
public GetSourceResponse(Map<String, Object> source) {
this.source = source;
}
public static GetSourceResponse fromXContent(XContentParser parser) throws IOException {
return new GetSourceResponse(parser.map());
}
public Map<String, Object> getSource() {
return this.source;
}
@Override
public String toString() {
return source.toString();
}
}

View File

@ -38,6 +38,8 @@ import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.core.GetSourceRequest;
import org.elasticsearch.client.core.GetSourceResponse;
import org.elasticsearch.client.core.MultiTermVectorsRequest;
import org.elasticsearch.client.core.MultiTermVectorsResponse;
import org.elasticsearch.client.core.TermVectorsRequest;
@ -70,6 +72,7 @@ import org.joda.time.format.DateTimeFormat;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@ -456,6 +459,71 @@ public class CrudIT extends ESRestHighLevelClientTestCase {
assertEquals("id2", secondResponse.getId());
}
public void testGetSource() throws IOException {
{
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
() -> execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync));
assertEquals(RestStatus.NOT_FOUND, exception.status());
assertEquals("Elasticsearch exception [type=index_not_found_exception, reason=no such index [index]]", exception.getMessage());
assertEquals("index", exception.getMetadata("es.index").get(0));
}
IndexRequest index = new IndexRequest("index").id("id");
String document = "{\"field1\":\"value1\",\"field2\":\"value2\"}";
index.source(document, XContentType.JSON);
index.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
highLevelClient().index(index, RequestOptions.DEFAULT);
{
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
GetSourceResponse response = execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync);
Map<String, Object> expectedResponse = new HashMap<>();
expectedResponse.put("field1", "value1");
expectedResponse.put("field2", "value2");
assertEquals(expectedResponse, response.getSource());
}
{
GetSourceRequest getRequest = new GetSourceRequest("index", "does_not_exist");
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
() -> execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync));
assertEquals(RestStatus.NOT_FOUND, exception.status());
assertEquals("Elasticsearch exception [type=resource_not_found_exception, " +
"reason=Document not found [index]/[_doc]/[does_not_exist]]", exception.getMessage());
}
{
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
getRequest.fetchSourceContext(new FetchSourceContext(true, Strings.EMPTY_ARRAY, Strings.EMPTY_ARRAY));
GetSourceResponse response = execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync);
Map<String, Object> expectedResponse = new HashMap<>();
expectedResponse.put("field1", "value1");
expectedResponse.put("field2", "value2");
assertEquals(expectedResponse, response.getSource());
}
{
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
getRequest.fetchSourceContext(new FetchSourceContext(true, new String[]{"field1"}, Strings.EMPTY_ARRAY));
GetSourceResponse response = execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync);
Map<String, Object> expectedResponse = new HashMap<>();
expectedResponse.put("field1", "value1");
assertEquals(expectedResponse, response.getSource());
}
{
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
getRequest.fetchSourceContext(new FetchSourceContext(true, Strings.EMPTY_ARRAY, new String[]{"field1"}));
GetSourceResponse response = execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync);
Map<String, Object> expectedResponse = new HashMap<>();
expectedResponse.put("field2", "value2");
assertEquals(expectedResponse, response.getSource());
}
{
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
getRequest.fetchSourceContext(new FetchSourceContext(false));
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
() -> execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync));
assertEquals("Elasticsearch exception [type=action_request_validation_exception, " +
"reason=Validation Failed: 1: fetching source can not be disabled;]", exception.getMessage());
}
}
public void testIndex() throws IOException {
final XContentType xContentType = randomFrom(XContentType.values());
{

View File

@ -54,6 +54,7 @@ import org.elasticsearch.action.support.replication.ReplicationRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestConverters.EndpointBuilder;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.GetSourceRequest;
import org.elasticsearch.client.core.MultiTermVectorsRequest;
import org.elasticsearch.client.core.TermVectorsRequest;
import org.elasticsearch.client.indices.AnalyzeRequest;
@ -172,6 +173,10 @@ public class RequestConvertersTests extends ESTestCase {
doTestSourceExists((index, id) -> new GetRequest(index, type, id));
}
public void testGetSource() throws IOException {
doTestGetSource((index, id) -> new GetSourceRequest(index, id));
}
private static void doTestSourceExists(BiFunction<String, String, GetRequest> requestFunction) throws IOException {
String index = randomAlphaOfLengthBetween(3, 10);
String id = randomAlphaOfLengthBetween(3, 10);
@ -215,6 +220,44 @@ public class RequestConvertersTests extends ESTestCase {
assertNull(request.getEntity());
}
private static void doTestGetSource(BiFunction<String, String, GetSourceRequest> requestFunction) throws IOException {
String index = randomAlphaOfLengthBetween(3, 10);
String id = randomAlphaOfLengthBetween(3, 10);
final GetSourceRequest getRequest = requestFunction.apply(index, id);
Map<String, String> expectedParams = new HashMap<>();
if (randomBoolean()) {
String preference = randomAlphaOfLengthBetween(3, 10);
getRequest.preference(preference);
expectedParams.put("preference", preference);
}
if (randomBoolean()) {
String routing = randomAlphaOfLengthBetween(3, 10);
getRequest.routing(routing);
expectedParams.put("routing", routing);
}
if (randomBoolean()) {
boolean realtime = randomBoolean();
getRequest.realtime(realtime);
if (realtime == false) {
expectedParams.put("realtime", "false");
}
}
if (randomBoolean()) {
boolean refresh = randomBoolean();
getRequest.refresh(refresh);
if (refresh) {
expectedParams.put("refresh", "true");
}
}
Request request = RequestConverters.getSource(getRequest);
assertEquals(HttpGet.METHOD_NAME, request.getMethod());
assertEquals("/" + index + "/_source/" + id, request.getEndpoint());
assertEquals(expectedParams, request.getParameters());
assertNull(request.getEntity());
}
public void testMultiGet() throws IOException {
Map<String, String> expectedParams = new HashMap<>();
MultiGetRequest multiGetRequest = new MultiGetRequest();

View File

@ -777,7 +777,6 @@ public class RestHighLevelClientTests extends ESTestCase {
"create",
"get_script_context",
"get_script_languages",
"get_source",
"indices.exists_type",
"indices.get_upgrade",
"indices.put_alias",

View File

@ -0,0 +1,73 @@
/*
* 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.AbstractResponseTestCase;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import static org.hamcrest.CoreMatchers.equalTo;
public final class GetSourceResponseTests extends
AbstractResponseTestCase<GetSourceResponseTests.SourceOnlyResponse, GetSourceResponse> {
static class SourceOnlyResponse implements ToXContentObject {
private final BytesReference source;
SourceOnlyResponse(BytesReference source) {
this.source = source;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
// this implementation copied from RestGetSourceAction.RestGetSourceResponseListener::buildResponse
try (InputStream stream = source.streamInput()) {
builder.rawValue(stream, XContentHelper.xContentType(source));
}
return builder;
}
}
@Override
protected SourceOnlyResponse createServerTestInstance(XContentType xContentType) {
BytesReference source = new BytesArray("{\"field\":\"value\"}");
return new SourceOnlyResponse(source);
}
@Override
protected GetSourceResponse doParseToClientInstance(XContentParser parser) throws IOException {
return GetSourceResponse.fromXContent(parser);
}
@Override
protected void assertInstances(SourceOnlyResponse serverTestInstance, GetSourceResponse clientInstance) {
assertThat(clientInstance.getSource(), equalTo(Collections.singletonMap("field", "value")));
}
}

View File

@ -53,6 +53,8 @@ import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.RethrottleRequest;
import org.elasticsearch.client.core.GetSourceRequest;
import org.elasticsearch.client.core.GetSourceResponse;
import org.elasticsearch.client.core.MultiTermVectorsRequest;
import org.elasticsearch.client.core.MultiTermVectorsResponse;
import org.elasticsearch.client.core.TermVectorsRequest;
@ -1398,6 +1400,103 @@ public class CRUDDocumentationIT extends ESRestHighLevelClientTestCase {
}
}
public void testGetSource() throws Exception {
RestHighLevelClient client = highLevelClient();
{
Request createIndex = new Request("PUT", "/posts");
createIndex.setJsonEntity(
"{\n" +
" \"mappings\" : {\n" +
" \"properties\" : {\n" +
" \"message\" : {\n" +
" \"type\": \"text\",\n" +
" \"store\": true\n" +
" }\n" +
" }\n" +
" }\n" +
"}");
Response response = client().performRequest(createIndex);
assertEquals(200, response.getStatusLine().getStatusCode());
IndexRequest indexRequest = new IndexRequest("posts").id("1")
.source("user", "kimchy",
"postDate", new Date(),
"message", "trying out Elasticsearch");
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult());
}
// tag::get-source-request
GetSourceRequest getSourceRequest = new GetSourceRequest(
"posts", // <1>
"1"); // <2>
// end::get-source-request
//tag::get-source-request-optional
String[] includes = Strings.EMPTY_ARRAY; // <2>
String[] excludes = new String[]{"postDate"};
getSourceRequest.fetchSourceContext(
new FetchSourceContext(true, includes, excludes)); // <1>
// end::get-source-request-optional
//tag::get-source-request-routing
getSourceRequest.routing("routing"); // <1>
//end::get-source-request-routing
//tag::get-source-request-preference
getSourceRequest.preference("preference"); // <1>
//end::get-source-request-preference
//tag::get-source-request-realtime
getSourceRequest.realtime(false); // <1>
//end::get-source-request-realtime
//tag::get-source-request-refresh
getSourceRequest.refresh(true); // <1>
//end::get-source-request-refresh
{
// tag::get-source-execute
GetSourceResponse response =
client.getSource(getSourceRequest, RequestOptions.DEFAULT);
// end::get-source-execute
// tag::get-source-response
Map<String, Object> source = response.getSource();
// end::get-source-response
Map<String, Object> expectSource = new HashMap<>();
expectSource.put("user", "kimchy");
expectSource.put("message", "trying out Elasticsearch");
assertEquals(expectSource, source);
}
{
GetSourceRequest request = new GetSourceRequest("posts", "1");
// tag::get-source-execute-listener
ActionListener<GetSourceResponse> listener =
new ActionListener<GetSourceResponse>() {
@Override
public void onResponse(GetSourceResponse getResponse) {
// <1>
}
@Override
public void onFailure(Exception e) {
// <2>
}
};
// end::get-source-execute-listener
// Replace the empty listener by a blocking listener in test
final CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch);
//tag::get-source-execute-async
client.getSourceAsync(request, RequestOptions.DEFAULT, listener); // <1>
//end::get-source-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
}
public void testExists() throws Exception {
RestHighLevelClient client = highLevelClient();
// tag::exists-request

View File

@ -0,0 +1,72 @@
--
:api: get-source
:request: GetSourceRequest
:response: GetSourceResponse
--
[id="{upid}-{api}"]
=== Get Source API
This API helps to get only the `_source` field of a document.
[id="{upid}-{api}-request"]
==== Get Source Request
A +{request}+ requires the following arguments:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-request]
--------------------------------------------------
<1> Index
<2> Document id
[id="{upid}-{api}-request-optional"]
==== Optional arguments
The following arguments can optionally be provided:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-request-optional]
--------------------------------------------------
<1> `FetchSourceContext` 's first argument `fetchSource` must be `true`, otherwise
`ElasticsearchException` get thrown
<2> Arguments of the context `excludes` and `includes` are optional
(see examples in Get API documentation)
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-request-routing]
--------------------------------------------------
<1> Routing value
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-request-preference]
--------------------------------------------------
<1> Preference value
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-request-realtime]
--------------------------------------------------
<1> Set realtime flag to `false` (`true` by default)
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-request-refresh]
--------------------------------------------------
<1> Perform a refresh before retrieving the document (`false` by default)
include::../execution.asciidoc[]
[id="{upid}-{api}-response"]
==== Get Source Response
The returned +{response}+ contains the field `source` that represents the
source of a document as a map.
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-response]
--------------------------------------------------

View File

@ -11,6 +11,7 @@ The Java High Level REST Client supports the following Document APIs:
Single document APIs::
* <<{upid}-index>>
* <<{upid}-get>>
* <<{upid}-get-source>>
* <<{upid}-exists>>
* <<{upid}-delete>>
* <<{upid}-update>>
@ -28,6 +29,7 @@ Multi-document APIs::
include::document/index.asciidoc[]
include::document/get.asciidoc[]
include::document/get-source.asciidoc[]
include::document/exists.asciidoc[]
include::document/delete.asciidoc[]
include::document/update.asciidoc[]