Search Template API

edit

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

edit

Inline Templates

edit

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

edit

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

edit

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

edit

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

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

Additional References

edit

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

Synchronous Execution

edit

The searchTemplate method executes the request synchronously:

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

Asynchronous Execution

edit

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

edit

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}.