Skip to content

Commit ae648c3

Browse files
committed
Add documentation.
1 parent 0003b8e commit ae648c3

File tree

3 files changed

+249
-0
lines changed

3 files changed

+249
-0
lines changed

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

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
package org.elasticsearch.client.documentation;
2121

22+
import org.apache.http.entity.ContentType;
23+
import org.apache.http.nio.entity.NStringEntity;
2224
import org.elasticsearch.action.ActionListener;
2325
import org.elasticsearch.action.LatchedActionListener;
2426
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
@@ -41,7 +43,11 @@
4143
import org.elasticsearch.action.support.IndicesOptions;
4244
import org.elasticsearch.action.support.WriteRequest;
4345
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
46+
import org.elasticsearch.client.Request;
47+
import org.elasticsearch.client.Response;
48+
import org.elasticsearch.client.RestClient;
4449
import org.elasticsearch.client.RestHighLevelClient;
50+
import org.elasticsearch.common.bytes.BytesReference;
4551
import org.elasticsearch.common.text.Text;
4652
import org.elasticsearch.common.unit.Fuzziness;
4753
import org.elasticsearch.common.unit.TimeValue;
@@ -60,6 +66,9 @@
6066
import org.elasticsearch.index.rankeval.RatedRequest;
6167
import org.elasticsearch.index.rankeval.RatedSearchHit;
6268
import org.elasticsearch.rest.RestStatus;
69+
import org.elasticsearch.script.ScriptType;
70+
import org.elasticsearch.script.mustache.SearchTemplateRequest;
71+
import org.elasticsearch.script.mustache.SearchTemplateResponse;
6372
import org.elasticsearch.search.Scroll;
6473
import org.elasticsearch.search.SearchHit;
6574
import org.elasticsearch.search.SearchHits;
@@ -92,6 +101,7 @@
92101
import java.util.ArrayList;
93102
import java.util.Arrays;
94103
import java.util.Collections;
104+
import java.util.HashMap;
95105
import java.util.List;
96106
import java.util.Map;
97107
import java.util.concurrent.CountDownLatch;
@@ -706,9 +716,128 @@ public void onFailure(Exception e) {
706716
}
707717
}
708718

719+
public void testSearchTemplateWithInlineScript() throws Exception {
720+
indexSearchTestData();
721+
RestHighLevelClient client = highLevelClient();
722+
723+
// tag::search-template-request-inline
724+
SearchTemplateRequest request = new SearchTemplateRequest();
725+
request.setRequest(new SearchRequest("posts")); // <1>
726+
727+
request.setScriptType(ScriptType.INLINE);
728+
request.setScript( // <2>
729+
"{" +
730+
" \"query\": { \"match\" : { \"{{field}}\" : \"{{value}}\" } }," +
731+
" \"size\" : \"{{size}}\"" +
732+
"}");
733+
734+
Map<String, Object> scriptParams = new HashMap<>();
735+
scriptParams.put("field", "title");
736+
scriptParams.put("value", "elasticsearch");
737+
scriptParams.put("size", 5);
738+
request.setScriptParams(scriptParams); // <3>
739+
// end::search-template-request-inline
740+
741+
// tag::search-template-response
742+
SearchTemplateResponse response = client.searchTemplate(request);
743+
SearchResponse searchResponse = response.getResponse();
744+
assertNotNull(searchResponse);
745+
assertTrue(searchResponse.getHits().totalHits > 0);
746+
// end::search-template-response
747+
748+
// tag::render-search-template-request
749+
request.setSimulate(true); // <1>
750+
// end::render-search-template-request
751+
752+
// tag::render-search-template-response
753+
SearchTemplateResponse renderResponse = client.searchTemplate(request);
754+
BytesReference source = renderResponse.getSource();
755+
assertNotNull(source);
756+
assertEquals((
757+
"{" +
758+
" \"size\" : \"5\"," +
759+
" \"query\": { \"match\" : { \"title\" : \"elasticsearch\" } }" +
760+
"}").replaceAll("\\s+", ""), source.utf8ToString());
761+
// end::render-search-template-response
762+
}
763+
764+
public void testSearchTemplateWithStoredScript() throws Exception {
765+
indexSearchTestData();
766+
RestHighLevelClient client = highLevelClient();
767+
RestClient restClient = client();
768+
769+
// tag::register-script
770+
Request scriptRequest = new Request("POST", "_scripts/title_search");
771+
scriptRequest.setEntity(new NStringEntity(
772+
"{" +
773+
" \"script\": {" +
774+
" \"lang\": \"mustache\"," +
775+
" \"source\": {" +
776+
" \"query\": { \"match\" : { \"{{field}}\" : \"{{value}}\" } }," +
777+
" \"size\" : \"{{size}}\"" +
778+
" }" +
779+
" }" +
780+
"}", ContentType.APPLICATION_JSON));
781+
Response scriptResponse = restClient.performRequest(scriptRequest);
782+
assertEquals(RestStatus.OK.getStatus(), scriptResponse.getStatusLine().getStatusCode());
783+
// end::register-script
784+
785+
// tag::search-template-request-stored
786+
SearchTemplateRequest request = new SearchTemplateRequest();
787+
request.setRequest(new SearchRequest("posts"));
788+
789+
request.setScriptType(ScriptType.STORED);
790+
request.setScript("title_search");
791+
792+
Map<String, Object> params = new HashMap<>();
793+
params.put("field", "title");
794+
params.put("value", "elasticsearch");
795+
params.put("size", 5);
796+
request.setScriptParams(params);
797+
// end::search-template-request-stored
798+
799+
// tag::search-template-request-options
800+
request.setExplain(true);
801+
request.setProfile(true);
802+
// end::search-template-request-options
803+
804+
// tag::search-template-execute
805+
SearchTemplateResponse response = client.searchTemplate(request);
806+
// end::search-template-execute
807+
808+
SearchResponse searchResponse = response.getResponse();
809+
assertNotNull(searchResponse);
810+
assertTrue(searchResponse.getHits().totalHits > 0);
811+
812+
// tag::search-template-execute-listener
813+
ActionListener<SearchTemplateResponse> listener = new ActionListener<SearchTemplateResponse>() {
814+
@Override
815+
public void onResponse(SearchTemplateResponse response) {
816+
// <1>
817+
}
818+
819+
@Override
820+
public void onFailure(Exception e) {
821+
// <2>
822+
}
823+
};
824+
// end::search-template-execute-listener
825+
826+
// Replace the empty listener by a blocking listener for tests.
827+
CountDownLatch latch = new CountDownLatch(1);
828+
listener = new LatchedActionListener<>(listener, latch);
829+
830+
// tag::search-template-execute-async
831+
client.searchTemplateAsync(request, listener); // <1>
832+
// end::search-template-execute-async
833+
834+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
835+
}
836+
709837
public void testFieldCaps() throws Exception {
710838
indexSearchTestData();
711839
RestHighLevelClient client = highLevelClient();
840+
712841
// tag::field-caps-request
713842
FieldCapabilitiesRequest request = new FieldCapabilitiesRequest()
714843
.fields("user")
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
[[java-rest-high-search-template]]
2+
=== Search Template API
3+
4+
The search template API allows for searches to be executed from a template based
5+
on the mustache language, and also for previewing rendered templates.
6+
7+
[[java-rest-high-search-template-request]]
8+
==== Search Template Request
9+
10+
===== Inline Templates
11+
12+
In the most basic form of request, the search template is specified inline:
13+
14+
["source","java",subs="attributes,callouts,macros"]
15+
--------------------------------------------------
16+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-template-request-inline]
17+
--------------------------------------------------
18+
<1> The search is executed against the `posts` index.
19+
<2> The template defines the structure of the search source. It is passed
20+
as a string because mustache templates are not always valid JSON.
21+
<3> Before running the search, the template is rendered with the provided parameters.
22+
23+
===== Registered Templates
24+
25+
Search templates can be registered in advance through stored scripts API. Note that
26+
the stored scripts API is not yet available in the high-level REST client, so in this
27+
example we use the simple REST client.
28+
29+
["source","java",subs="attributes,callouts,macros"]
30+
--------------------------------------------------
31+
include-tagged::{doc-tests}/SearchDocumentationIT.java[register-script]
32+
--------------------------------------------------
33+
34+
Instead of providing an inline script, we can refer to this registered template in the request:
35+
36+
["source","java",subs="attributes,callouts,macros"]
37+
--------------------------------------------------
38+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-template-request-stored]
39+
--------------------------------------------------
40+
41+
===== Rendering Templates
42+
43+
Given parameter values, a template can be rendered without executing a search:
44+
45+
["source","java",subs="attributes,callouts,macros"]
46+
--------------------------------------------------
47+
include-tagged::{doc-tests}/SearchDocumentationIT.java[render-search-template-request]
48+
--------------------------------------------------
49+
<1> Setting `simulate` to `true` causes the search template to only be rendered.
50+
51+
Both inline and pre-registered templates can be rendered.
52+
53+
===== Optional Arguments
54+
55+
As in standard search requests, the `explain` and `profile` options are supported:
56+
57+
["source","java",subs="attributes,callouts,macros"]
58+
--------------------------------------------------
59+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-template-request-options]
60+
--------------------------------------------------
61+
62+
===== Additional References
63+
64+
The https://www.elastic.co/guide/en/elasticsearch/reference/current/search-template.html#search-template[Search Template HTTP documentation]
65+
contains further examples of how search requests can be templated. For more detailed information on how mustache
66+
works and what can be done with it, please consult the http://mustache.github.io/mustache.5.html[online documentation of the mustache project].
67+
68+
[[java-rest-high-search-template-sync]]
69+
==== Synchronous Execution
70+
71+
The `searchTemplate` method executes the request synchronously:
72+
73+
["source","java",subs="attributes,callouts,macros"]
74+
--------------------------------------------------
75+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-template-execute]
76+
--------------------------------------------------
77+
78+
==== Asynchronous Execution
79+
80+
A search template request can be executed asynchronously through the `searchTemplateAsync`
81+
method:
82+
83+
["source","java",subs="attributes,callouts,macros"]
84+
--------------------------------------------------
85+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-template-execute-async]
86+
--------------------------------------------------
87+
<1> The `SearchTemplateRequest` to execute and the `ActionListener` to call when the execution completes.
88+
89+
The asynchronous method does not block and returns immediately. Once the request completes, the
90+
`ActionListener` is called back using the `onResponse` method if the execution completed successfully,
91+
or using the `onFailure` method if it failed.
92+
93+
A typical listener for `SearchTemplateResponse` is constructed as follows:
94+
95+
["source","java",subs="attributes,callouts,macros"]
96+
--------------------------------------------------
97+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-template-execute-listener]
98+
--------------------------------------------------
99+
<1> Called when the execution is successfully completed.
100+
<2> Called when the whole `SearchTemplateRequest` fails.
101+
102+
==== Search Template Response
103+
104+
For a standard search template request, the response contains a `SearchResponse` object
105+
with the result of executing the search:
106+
107+
["source","java",subs="attributes,callouts,macros"]
108+
--------------------------------------------------
109+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-template-response]
110+
--------------------------------------------------
111+
112+
If `simulate` was set to `true` in the request, then the response
113+
will contain the rendered search source instead of a `SearchResponse`:
114+
115+
["source","java",subs="attributes,callouts,macros"]
116+
--------------------------------------------------
117+
include-tagged::{doc-tests}/SearchDocumentationIT.java[render-search-template-response]
118+
--------------------------------------------------

docs/java-rest/high-level/supported-apis.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ The Java High Level REST Client supports the following Search APIs:
3131
* <<java-rest-high-search>>
3232
* <<java-rest-high-search-scroll>>
3333
* <<java-rest-high-clear-scroll>>
34+
* <<java-rest-high-search-template>>
3435
* <<java-rest-high-multi-search>>
3536
* <<java-rest-high-field-caps>>
3637
* <<java-rest-high-rank-eval>>
3738

3839
include::search/search.asciidoc[]
3940
include::search/scroll.asciidoc[]
4041
include::search/multi-search.asciidoc[]
42+
include::search/search-template.asciidoc[]
4143
include::search/field-caps.asciidoc[]
4244
include::search/rank-eval.asciidoc[]
4345

0 commit comments

Comments
 (0)