[Docs] Add profile section to the Search API documentation (#25880)
This commit is contained in:
parent
ca4f77039c
commit
90ebaaa9a8
|
@ -23,6 +23,7 @@ import org.elasticsearch.action.ActionListener;
|
|||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
import org.elasticsearch.action.bulk.BulkResponse;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.index.IndexResponse;
|
||||
import org.elasticsearch.action.search.ClearScrollRequest;
|
||||
import org.elasticsearch.action.search.ClearScrollResponse;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
|
@ -52,6 +53,11 @@ import org.elasticsearch.search.aggregations.metrics.avg.Avg;
|
|||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
|
||||
import org.elasticsearch.search.profile.ProfileResult;
|
||||
import org.elasticsearch.search.profile.ProfileShardResult;
|
||||
import org.elasticsearch.search.profile.aggregation.AggregationProfileShardResult;
|
||||
import org.elasticsearch.search.profile.query.CollectorResult;
|
||||
import org.elasticsearch.search.profile.query.QueryProfileShardResult;
|
||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||
import org.elasticsearch.search.sort.ScoreSortBuilder;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
|
@ -70,6 +76,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
|
||||
/**
|
||||
|
@ -105,7 +112,7 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
Arrays.asList("kimchy", "tanguy"), "innerObject", Collections.singletonMap("key", "value")));
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
BulkResponse bulkResponse = client.bulk(request);
|
||||
assertSame(bulkResponse.status(), RestStatus.OK);
|
||||
assertSame(RestStatus.OK, bulkResponse.status());
|
||||
assertFalse(bulkResponse.hasFailures());
|
||||
}
|
||||
{
|
||||
|
@ -244,7 +251,7 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
.source(XContentType.JSON, "company", "Elastic", "age", 40));
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
BulkResponse bulkResponse = client.bulk(request);
|
||||
assertSame(bulkResponse.status(), RestStatus.OK);
|
||||
assertSame(RestStatus.OK, bulkResponse.status());
|
||||
assertFalse(bulkResponse.hasFailures());
|
||||
}
|
||||
{
|
||||
|
@ -317,7 +324,7 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
request.add(new IndexRequest("posts", "doc", "4").source(XContentType.JSON, "user", "cbuescher"));
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
BulkResponse bulkResponse = client.bulk(request);
|
||||
assertSame(bulkResponse.status(), RestStatus.OK);
|
||||
assertSame(RestStatus.OK, bulkResponse.status());
|
||||
assertFalse(bulkResponse.hasFailures());
|
||||
}
|
||||
{
|
||||
|
@ -364,7 +371,7 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
Arrays.asList("kimchy", "tanguy"), "innerObject", Collections.singletonMap("key", "value")));
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
BulkResponse bulkResponse = client.bulk(request);
|
||||
assertSame(bulkResponse.status(), RestStatus.OK);
|
||||
assertSame(RestStatus.OK, bulkResponse.status());
|
||||
assertFalse(bulkResponse.hasFailures());
|
||||
}
|
||||
{
|
||||
|
@ -412,6 +419,74 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testSearchRequestProfiling() throws IOException {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
{
|
||||
IndexRequest request = new IndexRequest("posts", "doc", "1")
|
||||
.source(XContentType.JSON, "tags", "elasticsearch", "comments", 123);
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
|
||||
IndexResponse indexResponse = client.index(request);
|
||||
assertSame(RestStatus.CREATED, indexResponse.status());
|
||||
}
|
||||
{
|
||||
SearchRequest searchRequest = new SearchRequest();
|
||||
// tag::search-request-profiling
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
searchSourceBuilder.profile(true);
|
||||
// end::search-request-profiling
|
||||
searchSourceBuilder.query(QueryBuilders.termQuery("tags", "elasticsearch"));
|
||||
searchSourceBuilder.aggregation(AggregationBuilders.histogram("by_comments").field("comments").interval(100));
|
||||
searchRequest.source(searchSourceBuilder);
|
||||
|
||||
SearchResponse searchResponse = client.search(searchRequest);
|
||||
// tag::search-request-profiling-get
|
||||
Map<String, ProfileShardResult> profilingResults = searchResponse.getProfileResults(); // <1>
|
||||
for (Map.Entry<String, ProfileShardResult> profilingResult : profilingResults.entrySet()) { // <2>
|
||||
String key = profilingResult.getKey(); // <3>
|
||||
ProfileShardResult profileShardResult = profilingResult.getValue(); // <4>
|
||||
}
|
||||
// end::search-request-profiling-get
|
||||
|
||||
ProfileShardResult profileShardResult = profilingResults.values().iterator().next();
|
||||
assertNotNull(profileShardResult);
|
||||
|
||||
// tag::search-request-profiling-queries
|
||||
List<QueryProfileShardResult> queryProfileShardResults = profileShardResult.getQueryProfileResults(); // <1>
|
||||
for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) { // <2>
|
||||
|
||||
}
|
||||
// end::search-request-profiling-queries
|
||||
assertThat(queryProfileShardResults.size(), equalTo(1));
|
||||
|
||||
for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) {
|
||||
// tag::search-request-profiling-queries-results
|
||||
for (ProfileResult profileResult : queryProfileResult.getQueryResults()) { // <1>
|
||||
String queryName = profileResult.getQueryName(); // <2>
|
||||
long queryTimeInMillis = profileResult.getTime(); // <3>
|
||||
List<ProfileResult> profiledChildren = profileResult.getProfiledChildren(); // <4>
|
||||
}
|
||||
// end::search-request-profiling-queries-results
|
||||
|
||||
// tag::search-request-profiling-queries-collectors
|
||||
CollectorResult collectorResult = queryProfileResult.getCollectorResult(); // <1>
|
||||
String collectorName = collectorResult.getName(); // <2>
|
||||
Long collectorTimeInMillis = collectorResult.getTime(); // <3>
|
||||
List<CollectorResult> profiledChildren = collectorResult.getProfiledChildren(); // <4>
|
||||
// end::search-request-profiling-queries-collectors
|
||||
}
|
||||
|
||||
// tag::search-request-profiling-aggs
|
||||
AggregationProfileShardResult aggsProfileResults = profileShardResult.getAggregationProfileResults(); // <1>
|
||||
for (ProfileResult profileResult : aggsProfileResults.getProfileResults()) { // <2>
|
||||
String aggName = profileResult.getQueryName(); // <3>
|
||||
long aggTimeInMillis = profileResult.getTime(); // <4>
|
||||
List<ProfileResult> profiledChildren = profileResult.getProfiledChildren(); // <5>
|
||||
}
|
||||
// end::search-request-profiling-aggs
|
||||
assertThat(aggsProfileResults.getProfileResults().size(), equalTo(1));
|
||||
}
|
||||
}
|
||||
|
||||
public void testScroll() throws IOException {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
{
|
||||
|
@ -424,7 +499,7 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
.source(XContentType.JSON, "title", "The Future of Federated Search in Elasticsearch"));
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
BulkResponse bulkResponse = client.bulk(request);
|
||||
assertSame(bulkResponse.status(), RestStatus.OK);
|
||||
assertSame(RestStatus.OK, bulkResponse.status());
|
||||
assertFalse(bulkResponse.hasFailures());
|
||||
}
|
||||
{
|
||||
|
|
|
@ -163,6 +163,19 @@ the text `kmichy`
|
|||
We will later see how to <<java-rest-high-retrieve-suggestions,retrieve suggestions>> from the
|
||||
`SearchResponse`.
|
||||
|
||||
===== Profiling Queries and Aggregations
|
||||
|
||||
The {ref}/search-profile.html[Profile API] can be used to profile the execution of queries and aggregations for
|
||||
a specific search request. in order to use it, the profile flag must be set to true on the `SearchSourceBuilder`:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling]
|
||||
--------------------------------------------------
|
||||
|
||||
Once the `SearchRequest` is executed the corresponding `SearchResponse` will
|
||||
<<java-rest-high-retrieve-profile-results,contain the profiling results>>.
|
||||
|
||||
[[java-rest-high-document-search-sync]]
|
||||
==== Synchronous Execution
|
||||
|
||||
|
@ -339,3 +352,77 @@ include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-suggestion
|
|||
type of Suggestion class (here `TermSuggestion`), otherwise a `ClassCastException` is thrown
|
||||
<3> Iterate over the suggestion entries
|
||||
<4> Iterate over the options in one entry
|
||||
|
||||
[[java-rest-high-retrieve-profile-results]]
|
||||
===== Retrieving Profiling Results
|
||||
|
||||
Profiling results are retrieved from a `SearchResponse` using the `getProfileResults()` method. This
|
||||
method returns a `Map` containing a `ProfileShardResult` object for every shard involved in the
|
||||
`SearchRequest` execution. `ProfileShardResult` are stored in the `Map` using a key that uniquely
|
||||
identifies the shard the profile result corresponds to.
|
||||
|
||||
Here is a sample code that shows how to iterate over all the profiling results of every shard:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-get]
|
||||
--------------------------------------------------
|
||||
<1> Retrieve the `Map` of `ProfileShardResult` from the `SearchResponse`
|
||||
<2> Profiling results can be retrieved by shard's key if the key is known, otherwise it might be simpler
|
||||
to iterate over all the profiling results
|
||||
<3> Retrieve the key that identifies which shard the `ProfileShardResult` belongs to
|
||||
<4> Retrieve the `ProfileShardResult` for the given shard
|
||||
|
||||
The `ProfileShardResult` object itself contains one or more query profile results, one for each query
|
||||
executed against the underlying Lucene index:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-queries]
|
||||
--------------------------------------------------
|
||||
<1> Retrieve the list of `QueryProfileShardResult`
|
||||
<2> Iterate over each `QueryProfileShardResult`
|
||||
|
||||
Each `QueryProfileShardResult` gives access to the detailed query tree execution, returned as a list of
|
||||
`ProfileResult` objects:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-queries-results]
|
||||
--------------------------------------------------
|
||||
<1> Iterate over the profile results
|
||||
<2> Retrieve the name of the Lucene query
|
||||
<3> Retrieve the time in millis spent executing the Lucene query
|
||||
<4> Retrieve the profile results for the sub-queries (if any)
|
||||
|
||||
The Rest API documentation contains more information about {ref}/_profiling_queries.html[Profiling Queries] with
|
||||
a description of the {ref}/_profiling_queries.html#_literal_query_literal_section[query profiling information]
|
||||
|
||||
The `QueryProfileShardResult` also gives access to the profiling information for the Lucene collectors:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-queries-collectors]
|
||||
--------------------------------------------------
|
||||
<1> Retrieve the profiling result of the Lucene collector
|
||||
<2> Retrieve the name of the Lucene collector
|
||||
<3> Retrieve the time in millis spent executing the Lucene collector
|
||||
<4> Retrieve the profile results for the sub-collectors (if any)
|
||||
|
||||
The Rest API documentation contains more information about profiling information
|
||||
{ref}/_profiling_queries.html#_literal_collectors_literal_section[for Lucene collectors].
|
||||
|
||||
In a very similar manner to the query tree execution, the `QueryProfileShardResult` objects gives access
|
||||
to the detailed aggregations tree execution:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-aggs]
|
||||
--------------------------------------------------
|
||||
<1> Retrieve the `AggregationProfileShardResult`
|
||||
<2> Iterate over the aggregation profile results
|
||||
<3> Retrieve the type of the aggregation (corresponds to Java class used to execute the aggregation)
|
||||
<4> Retrieve the time in millis spent executing the Lucene collector
|
||||
<5> Retrieve the profile results for the sub-aggregations (if any)
|
||||
|
||||
The Rest API documentation contains more information about {ref}/_profiling_aggregations.html[Profiling Aggregations]
|
||||
|
|
Loading…
Reference in New Issue