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 106caea027e..2ff944b0a53 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
@@ -261,6 +261,18 @@ final class RequestConverters {
return request;
}
+
+ static Request sourceExists(GetRequest getRequest) {
+ Request request = new Request(HttpHead.METHOD_NAME, endpoint(getRequest.index(), getRequest.type(), getRequest.id(), "_source"));
+
+ Params parameters = new Params(request);
+ 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
+ return request;
+ }
static Request multiGet(MultiGetRequest multiGetRequest) throws IOException {
Request request = new Request(HttpPost.METHOD_NAME, "/_mget");
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 342e3efbb6a..7e8a9653614 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
@@ -727,6 +727,32 @@ public class RestHighLevelClient implements Closeable {
emptySet());
}
+ /**
+ * Checks for the existence of a document with a "_source" field. Returns true if it exists, false otherwise.
+ * See Source exists API
+ * on elastic.co
+ * @param getRequest the request
+ * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+ * @return true
if the document and _source field exists, false
otherwise
+ * @throws IOException in case there is a problem sending the request
+ */
+ public boolean existsSource(GetRequest getRequest, RequestOptions options) throws IOException {
+ return performRequest(getRequest, RequestConverters::sourceExists, options, RestHighLevelClient::convertExistsResponse, emptySet());
+ }
+
+ /**
+ * Asynchronously checks for the existence of a document with a "_source" field. Returns true if it exists, false otherwise.
+ * See Source exists API
+ * on elastic.co
+ * @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
+ */
+ public final void existsSourceAsync(GetRequest getRequest, RequestOptions options, ActionListener listener) {
+ performRequestAsync(getRequest, RequestConverters::sourceExists, options, RestHighLevelClient::convertExistsResponse, listener,
+ emptySet());
+ }
+
/**
* Index a document using the Index API.
* See Index API on elastic.co
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 e679a85f67f..1dd27cff0d9 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
@@ -194,6 +194,61 @@ public class CrudIT extends ESRestHighLevelClientTestCase {
assertFalse(execute(getRequest, highLevelClient()::exists, highLevelClient()::existsAsync));
}
}
+
+ public void testSourceExists() throws IOException {
+ {
+ GetRequest getRequest = new GetRequest("index", "type", "id");
+ assertFalse(execute(getRequest, highLevelClient()::existsSource, highLevelClient()::existsSourceAsync));
+ }
+ IndexRequest index = new IndexRequest("index", "type", "id");
+ index.source("{\"field1\":\"value1\",\"field2\":\"value2\"}", XContentType.JSON);
+ index.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
+ highLevelClient().index(index, RequestOptions.DEFAULT);
+ {
+ GetRequest getRequest = new GetRequest("index", "type", "id");
+ assertTrue(execute(getRequest, highLevelClient()::existsSource, highLevelClient()::existsSourceAsync));
+ }
+ {
+ GetRequest getRequest = new GetRequest("index", "type", "does_not_exist");
+ assertFalse(execute(getRequest, highLevelClient()::existsSource, highLevelClient()::existsSourceAsync));
+ }
+ {
+ GetRequest getRequest = new GetRequest("index", "type", "does_not_exist").version(1);
+ assertFalse(execute(getRequest, highLevelClient()::existsSource, highLevelClient()::existsSourceAsync));
+ }
+ }
+
+ public void testSourceDoesNotExist() throws IOException {
+ final String noSourceIndex = "no_source";
+ {
+ // Prepare
+ Settings settings = Settings.builder()
+ .put("number_of_shards", 1)
+ .put("number_of_replicas", 0)
+ .build();
+ String mapping = "\"_doc\": { \"_source\": {\n" +
+ " \"enabled\": false\n" +
+ " } }";
+ createIndex(noSourceIndex, settings, mapping);
+ assertEquals(
+ RestStatus.OK,
+ highLevelClient().bulk(
+ new BulkRequest()
+ .add(new IndexRequest(noSourceIndex, "_doc", "1")
+ .source(Collections.singletonMap("foo", 1), XContentType.JSON))
+ .add(new IndexRequest(noSourceIndex, "_doc", "2")
+ .source(Collections.singletonMap("foo", 2), XContentType.JSON))
+ .setRefreshPolicy(RefreshPolicy.IMMEDIATE),
+ RequestOptions.DEFAULT
+ ).status()
+ );
+ }
+ {
+ GetRequest getRequest = new GetRequest(noSourceIndex, "_doc", "1");
+ assertTrue(execute(getRequest, highLevelClient()::exists, highLevelClient()::existsAsync));
+ assertFalse(execute(getRequest, highLevelClient()::existsSource, highLevelClient()::existsSourceAsync));
+ }
+ }
public void testGet() throws IOException {
{
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 8f4ec4cc0cc..d40c3196e54 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
@@ -650,7 +650,6 @@ public class RestHighLevelClientTests extends ESTestCase {
"cluster.remote_info",
"count",
"create",
- "exists_source",
"get_source",
"indices.delete_alias",
"indices.delete_template",
diff --git a/docs/java-rest/high-level/document/exists.asciidoc b/docs/java-rest/high-level/document/exists.asciidoc
index ac6968d1f37..3a09203bab6 100644
--- a/docs/java-rest/high-level/document/exists.asciidoc
+++ b/docs/java-rest/high-level/document/exists.asciidoc
@@ -29,3 +29,10 @@ include-tagged::{doc-tests-file}[{api}-request]
<5> Disable fetching stored fields.
include::../execution.asciidoc[]
+
+
+==== Source exists request
+A variant of the exists request is `existsSource` method which has the additional check
+that the document in question has stored the `source`. If the mapping for the index has opted
+to remove support for storing JSON source in documents then this method will return false
+for documents in this index.