Search Template API

The search template API allows for searches to be executed from a template based on the mustache language, and also for previewing rendered templates.

Search Template Request

Inline Templates

In the most basic form of request, the search template is specified inline:

SearchTemplateRequest request = new SearchTemplateRequest();
request.setRequest(new SearchRequest("posts")); 

request.setScriptType(ScriptType.INLINE);
request.setScript( 
    "{" +
    "  \"query\": { \"match\" : { \"{{field}}\" : \"{{value}}\" } }," +
    "  \"size\" : \"{{size}}\"" +
    "}");

Map<String, Object> scriptParams = new HashMap<>();
scriptParams.put("field", "title");
scriptParams.put("value", "elasticsearch");
scriptParams.put("size", 5);
request.setScriptParams(scriptParams); 

The search is executed against the posts index.

The template defines the structure of the search source. It is passed as a string because mustache templates are not always valid JSON.

Before running the search, the template is rendered with the provided parameters.

Registered Templates

Search templates can be registered in advance through stored scripts API. Note that the stored scripts API is not yet available in the high-level REST client, so in this example we use the low-level REST client.

Request scriptRequest = new Request("POST", "_scripts/title_search");
scriptRequest.setJsonEntity(
    "{" +
    "  \"script\": {" +
    "    \"lang\": \"mustache\"," +
    "    \"source\": {" +
    "      \"query\": { \"match\" : { \"{{field}}\" : \"{{value}}\" } }," +
    "      \"size\" : \"{{size}}\"" +
    "    }" +
    "  }" +
    "}");
Response scriptResponse = restClient.performRequest(scriptRequest);

Instead of providing an inline script, we can refer to this registered template in the request:

SearchTemplateRequest request = new SearchTemplateRequest();
request.setRequest(new SearchRequest("posts"));

request.setScriptType(ScriptType.STORED);
request.setScript("title_search");

Map<String, Object> params = new HashMap<>();
params.put("field", "title");
params.put("value", "elasticsearch");
params.put("size", 5);
request.setScriptParams(params);

Rendering Templates

Given parameter values, a template can be rendered without executing a search:

request.setSimulate(true); 

Setting simulate to true causes the search template to only be rendered.

Both inline and pre-registered templates can be rendered.

Optional Arguments

As in standard search requests, the explain and profile options are supported:

request.setExplain(true);
request.setProfile(true);

Additional References

The Search Template documentation contains further examples of how search requests can be templated.

Synchronous Execution

The searchTemplate method executes the request synchronously:

SearchTemplateResponse response = client.searchTemplate(request, RequestOptions.DEFAULT);

Asynchronous Execution

A search template request can be executed asynchronously through the searchTemplateAsync method:

client.searchTemplateAsync(request, RequestOptions.DEFAULT, listener); 

The SearchTemplateRequest to execute and the ActionListener to call when the execution completes.

The asynchronous method does not block and returns immediately. Once the request completes, the ActionListener is called back using the onResponse method if the execution completed successfully, or using the onFailure method if it failed.

A typical listener for SearchTemplateResponse is constructed as follows:

ActionListener<SearchTemplateResponse> listener = new ActionListener<SearchTemplateResponse>() {
    @Override
    public void onResponse(SearchTemplateResponse response) {
        
    }

    @Override
    public void onFailure(Exception e) {
        
    }
};

Called when the execution is successfully completed.

Called when the whole SearchTemplateRequest fails.

Search Template Response

For a standard search template request, the response contains a SearchResponse object with the result of executing the search:

SearchTemplateResponse response = client.searchTemplate(request, RequestOptions.DEFAULT);
SearchResponse searchResponse = response.getResponse();

If simulate was set to true in the request, then the response will contain the rendered search source instead of a SearchResponse:

SearchTemplateResponse renderResponse = client.searchTemplate(request, RequestOptions.DEFAULT);
BytesReference source = renderResponse.getSource(); 

The rendered source in bytes, in our example {"query": { "match" : { "title" : "elasticsearch" }}, "size" : 5}.