Browse Source

Add profile and explain parameters to template API

We can now run templates using `explain` and/or `profile` parameters.
Which is interesting when you have defined a complicated profile but want to debug it in an easier way than running the full query again.

You can use `explain` parameter when running a template:

```js
GET /_search/template
{
  "file": "my_template",
  "params": {
    "status": [ "pending", "published" ]
  },
  "explain": true
}
```

You can use `profile` parameter when running a template:

```js
GET /_search/template
{
  "file": "my_template",
  "params": {
    "status": [ "pending", "published" ]
  },
  "profile": true
}
```
David Pilato 9 years ago
parent
commit
ed4d0881b1

+ 36 - 0
docs/reference/search/search-template.asciidoc

@@ -486,6 +486,42 @@ GET /_render/template/<template_name>
 }
 ------------------------------------------
 
+[float]
+===== Explain
+
+You can use `explain` parameter when running a template:
+
+[source,js]
+------------------------------------------
+GET /_search/template
+{
+  "file": "my_template",
+  "params": {
+    "status": [ "pending", "published" ]
+  },
+  "explain": true
+}
+------------------------------------------
+
+
+[float]
+===== Profiling
+
+You can use `profile` parameter when running a template:
+
+[source,js]
+------------------------------------------
+GET /_search/template
+{
+  "file": "my_template",
+  "params": {
+    "status": [ "pending", "published" ]
+  },
+  "profile": true
+}
+------------------------------------------
+
+
 [[multi-search-template]]
 == Multi Search Template
 

+ 2 - 0
modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestSearchTemplateAction.java

@@ -68,6 +68,8 @@ public class RestSearchTemplateAction extends BaseRestHandler {
             request.setScriptType(ScriptService.ScriptType.STORED);
             request.setScript(s);
         }, new ParseField("id"));
+        PARSER.declareBoolean(SearchTemplateRequest::setExplain, new ParseField("explain"));
+        PARSER.declareBoolean(SearchTemplateRequest::setProfile, new ParseField("profile"));
         PARSER.declareField((parser, request, value) -> {
             request.setScriptType(ScriptService.ScriptType.INLINE);
             if (parser.currentToken() == XContentParser.Token.START_OBJECT) {

+ 22 - 0
modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/SearchTemplateRequest.java

@@ -41,6 +41,8 @@ public class SearchTemplateRequest extends ActionRequest<SearchTemplateRequest>
 
     private SearchRequest request;
     private boolean simulate = false;
+    private boolean explain = false;
+    private boolean profile = false;
     private ScriptService.ScriptType scriptType;
     private String script;
     private Map<String, Object> scriptParams;
@@ -69,6 +71,22 @@ public class SearchTemplateRequest extends ActionRequest<SearchTemplateRequest>
         this.simulate = simulate;
     }
 
+    public boolean isExplain() {
+        return explain;
+    }
+
+    public void setExplain(boolean explain) {
+        this.explain = explain;
+    }
+
+    public boolean isProfile() {
+        return profile;
+    }
+
+    public void setProfile(boolean profile) {
+        this.profile = profile;
+    }
+
     public ScriptService.ScriptType getScriptType() {
         return scriptType;
     }
@@ -123,6 +141,8 @@ public class SearchTemplateRequest extends ActionRequest<SearchTemplateRequest>
         super.readFrom(in);
         request = in.readOptionalStreamable(SearchRequest::new);
         simulate = in.readBoolean();
+        explain = in.readBoolean();
+        profile = in.readBoolean();
         scriptType = ScriptService.ScriptType.readFrom(in);
         script = in.readOptionalString();
         if (in.readBoolean()) {
@@ -135,6 +155,8 @@ public class SearchTemplateRequest extends ActionRequest<SearchTemplateRequest>
         super.writeTo(out);
         out.writeOptionalStreamable(request);
         out.writeBoolean(simulate);
+        out.writeBoolean(explain);
+        out.writeBoolean(profile);
         ScriptService.ScriptType.writeTo(scriptType, out);
         out.writeOptionalString(script);
         boolean hasParams = scriptParams != null;

+ 16 - 0
modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/SearchTemplateRequestBuilder.java

@@ -47,6 +47,22 @@ public class SearchTemplateRequestBuilder
         return this;
     }
 
+    /**
+     * Enables explanation for each hit on how its score was computed. Disabled by default
+     */
+    public SearchTemplateRequestBuilder setExplain(boolean explain) {
+        request.setExplain(explain);
+        return this;
+    }
+
+    /**
+     * Enables profiling of the query. Disabled by default
+     */
+    public SearchTemplateRequestBuilder setProfile(boolean profile) {
+        request.setProfile(profile);
+        return this;
+    }
+
     public SearchTemplateRequestBuilder setScriptType(ScriptService.ScriptType scriptType) {
         request.setScriptType(scriptType);
         return this;

+ 2 - 0
modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/TransportSearchTemplateAction.java

@@ -84,6 +84,8 @@ public class TransportSearchTemplateAction extends HandledTransportAction<Search
                 SearchSourceBuilder builder = SearchSourceBuilder.searchSource();
                 builder.parseXContent(new QueryParseContext(searchRequestParsers.queryParsers, parser, parseFieldMatcher),
                     searchRequestParsers.aggParsers, searchRequestParsers.suggesters, searchRequestParsers.searchExtParsers);
+                builder.explain(request.isExplain());
+                builder.profile(request.isProfile());
                 searchRequest.source(builder);
 
                 searchAction.execute(searchRequest, new ActionListener<SearchResponse>() {

+ 16 - 0
modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/30_search_template.yaml

@@ -106,3 +106,19 @@
 
   - match: { hits.total: 1 }
   - length: { hits.hits: 1 }
+
+  - do:
+      search_template:
+        body: { "file" : "template_1", "params": { "size": "2", "field": "otherField", "value": "foo" }, "explain" : true }
+
+  - match: { hits.total: 1 }
+  - length: { hits.hits: 1 }
+  - match: { hits.hits.0._explanation.description: "weight(otherField:foo in 0) [PerFieldSimilarity], result of:" }
+
+  - do:
+      search_template:
+        body: { "file" : "template_1", "params": { "size": "2", "field": "otherField", "value": "foo" }, "profile" : true }
+
+  - match: { hits.total: 1 }
+  - length: { hits.hits: 1 }
+  - length: { profile: 1 }

+ 8 - 0
rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json

@@ -46,6 +46,14 @@
           "type" : "enum",
           "options" : ["query_then_fetch", "query_and_fetch", "dfs_query_then_fetch", "dfs_query_and_fetch"],
           "description" : "Search operation type"
+        },
+        "explain": {
+          "type" : "boolean",
+          "description" : "Specify whether to return detailed information about score computation as part of a hit"
+        },
+        "profile": {
+          "type" : "boolean",
+          "description" : "Specify whether to profile the query execution"
         }
       }
     },