Skip to content

Commit a3cb994

Browse files
committed
Add support for the profile API
1 parent 650fcd1 commit a3cb994

File tree

13 files changed

+248
-35
lines changed

13 files changed

+248
-35
lines changed

src/Nest/Nest.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,12 @@
10941094
<Compile Include="Search\Search\InnerHits\NamedInnerHits.cs" />
10951095
<Compile Include="Search\Search\InnerHits\PathInnerHit.cs" />
10961096
<Compile Include="Search\Search\InnerHits\TypeInnerHit.cs" />
1097+
<Compile Include="Search\Search\Profile\Collector.cs" />
1098+
<Compile Include="Search\Search\Profile\Profile.cs" />
1099+
<Compile Include="Search\Search\Profile\QueryBreakdown.cs" />
1100+
<Compile Include="Search\Search\Profile\QueryProfile.cs" />
1101+
<Compile Include="Search\Search\Profile\SearchProfile.cs" />
1102+
<Compile Include="Search\Search\Profile\ShardProfile.cs" />
10971103
<Compile Include="Search\Search\Rescoring\Rescore.cs" />
10981104
<Compile Include="Search\Search\Rescoring\RescoreQuery.cs" />
10991105
<Compile Include="Search\Search\Rescoring\ScoreMode.cs" />
@@ -1232,4 +1238,4 @@
12321238
</ItemGroup>
12331239
</When>
12341240
</Choose>
1235-
</Project>
1241+
</Project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Nest
5+
{
6+
public class Collector
7+
{
8+
[JsonProperty("name")]
9+
public string Name { get; internal set; }
10+
11+
[JsonProperty("reason")]
12+
public string Reason { get; internal set; }
13+
14+
[JsonProperty("time")]
15+
public Time Time { get; internal set; }
16+
17+
[JsonProperty("children")]
18+
public IEnumerable<Collector> Children { get; internal set; }
19+
20+
21+
}
22+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Newtonsoft.Json;
4+
5+
namespace Nest
6+
{
7+
public class Profile
8+
{
9+
[JsonProperty("shards")]
10+
public IEnumerable<ShardProfile> Shards { get; internal set; }
11+
}
12+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Nest
4+
{
5+
public class QueryBreakdown
6+
{
7+
[JsonProperty("score")]
8+
public long Score { get; internal set; }
9+
10+
[JsonProperty("next_doc")]
11+
public long NextDoc { get; internal set; }
12+
13+
[JsonProperty("create_weight")]
14+
public long CreateWeight { get; internal set; }
15+
16+
[JsonProperty("build_scorer")]
17+
public long BuildScorer { get; internal set; }
18+
19+
[JsonProperty("advance")]
20+
public long Advance { get; internal set; }
21+
22+
[JsonProperty("match")]
23+
public long Match { get; internal set; }
24+
}
25+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Nest
5+
{
6+
public class QueryProfile
7+
{
8+
[JsonProperty("query_type")]
9+
public string QueryType { get; internal set; }
10+
11+
[JsonProperty("lucene")]
12+
public string Lucene { get; internal set; }
13+
14+
[JsonProperty("time")]
15+
public Time Time { get; internal set; }
16+
17+
[JsonProperty("breakdown")]
18+
public QueryBreakdown Breakdown { get; internal set; }
19+
20+
[JsonProperty("children")]
21+
public IEnumerable<QueryProfile> Children { get; internal set; }
22+
}
23+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Nest
5+
{
6+
public class SearchProfile
7+
{
8+
[JsonProperty("rewrite_time")]
9+
public long RewriteTime { get; internal set; }
10+
11+
[JsonProperty("query")]
12+
public IEnumerable<QueryProfile> Query { get; internal set; }
13+
14+
[JsonProperty("collector")]
15+
public IEnumerable<Collector> Collector { get; internal set; }
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Nest
5+
{
6+
public class ShardProfile
7+
{
8+
[JsonProperty("id")]
9+
public string Id { get; internal set; }
10+
11+
[JsonProperty("searches")]
12+
public IEnumerable<SearchProfile> Searches { get; internal set; }
13+
14+
}
15+
}

src/Nest/Search/Search/SearchRequest.cs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public partial interface ISearchRequest : ICovariantSearchRequest
2929
[JsonProperty(PropertyName = "track_scores")]
3030
bool? TrackScores { get; set; }
3131

32+
[JsonProperty(PropertyName = "profile")]
33+
bool? Profile { get; set; }
34+
3235
[JsonProperty(PropertyName = "min_score")]
3336
double? MinScore { get; set; }
3437

@@ -101,6 +104,7 @@ public partial class SearchRequest
101104
public bool? Explain { get; set; }
102105
public bool? Version { get; set; }
103106
public bool? TrackScores { get; set; }
107+
public bool? Profile { get; set; }
104108
public double? MinScore { get; set; }
105109
public long? TerminateAfter { get; set; }
106110
public Fields Fields { get; set; }
@@ -143,6 +147,7 @@ public partial class SearchRequest<T>
143147
public bool? Explain { get; set; }
144148
public bool? Version { get; set; }
145149
public bool? TrackScores { get; set; }
150+
public bool? Profile { get; set; }
146151
public double? MinScore { get; set; }
147152
public long? TerminateAfter { get; set; }
148153
public Fields Fields { get; set; }
@@ -198,6 +203,7 @@ public partial class SearchDescriptor<T> where T : class
198203
bool? ISearchRequest.Explain { get; set; }
199204
bool? ISearchRequest.Version { get; set; }
200205
bool? ISearchRequest.TrackScores { get; set; }
206+
bool? ISearchRequest.Profile { get; set; }
201207
double? ISearchRequest.MinScore { get; set; }
202208
long? ISearchRequest.TerminateAfter { get; set; }
203209

@@ -224,7 +230,7 @@ public SearchDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter>
224230
Assign(a => a.Source = sourceSelector?.Invoke(new SourceFilterDescriptor<T>()));
225231

226232
/// <summary>
227-
/// The number of hits to return. Defaults to 10. When using scroll search type
233+
/// The number of hits to return. Defaults to 10. When using scroll search type
228234
/// size is actually multiplied by the number of shards!
229235
/// </summary>
230236
public SearchDescriptor<T> Size(int size) => Assign(a => a.Size = size);
@@ -245,14 +251,14 @@ public SearchDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter>
245251
public SearchDescriptor<T> Skip(int skip) => this.From(skip);
246252

247253
/// <summary>
248-
/// A search timeout, bounding the search request to be executed within the
254+
/// A search timeout, bounding the search request to be executed within the
249255
/// specified time value and bail with the hits accumulated up
250256
/// to that point when expired. Defaults to no timeout.
251257
/// </summary>
252258
public SearchDescriptor<T> Timeout(string timeout) => Assign(a => a.Timeout = timeout);
253259

254260
/// <summary>
255-
/// Enables explanation for each hit on how its score was computed.
261+
/// Enables explanation for each hit on how its score was computed.
256262
/// (Use .DocumentsWithMetaData on the return results)
257263
/// </summary>
258264
public SearchDescriptor<T> Explain(bool explain = true) => Assign(a => a.Explain = explain);
@@ -267,20 +273,27 @@ public SearchDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter>
267273
/// </summary>
268274
public SearchDescriptor<T> TrackScores(bool trackscores = true) => Assign(a => a.TrackScores = trackscores);
269275

276+
/// <summary>
277+
/// The Profile API provides detailed timing information about the execution of individual components in a query.
278+
/// It gives the user insight into how queries are executed at a low level so that the user can understand
279+
/// why certain queries are slow, and take steps to improve their slow queries.
280+
/// </summary>
281+
public SearchDescriptor<T> Profile(bool profile = true) => Assign(a => a.Profile = profile);
282+
270283
/// <summary>
271284
/// Allows to filter out documents based on a minimum score:
272285
/// </summary>
273286
public SearchDescriptor<T> MinScore(double minScore) => Assign(a => a.MinScore = minScore);
274287

275288
/// <summary>
276-
/// The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early.
277-
/// If set, the response will have a boolean field terminated_early to indicate whether the query execution has actually terminated_early.
289+
/// The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early.
290+
/// If set, the response will have a boolean field terminated_early to indicate whether the query execution has actually terminated_early.
278291
/// </summary>
279292
public SearchDescriptor<T> TerminateAfter(long terminateAfter) => Assign(a => a.TerminateAfter = terminateAfter);
280293

281294
/// <summary>
282295
/// <para>
283-
/// Controls a preference of which shard replicas to execute the search request on.
296+
/// Controls a preference of which shard replicas to execute the search request on.
284297
/// By default, the operation is randomized between the each shard replicas.
285298
/// </para>
286299
/// <para>
@@ -291,19 +304,19 @@ public SearchDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter>
291304

292305
/// <summary>
293306
/// <para>
294-
/// Controls a preference of which shard replicas to execute the search request on.
307+
/// Controls a preference of which shard replicas to execute the search request on.
295308
/// By default, the operation is randomized between the each shard replicas.
296309
/// </para>
297310
/// <para>
298-
/// The operation will go and be executed on the primary shard, and if not available (failover),
311+
/// The operation will go and be executed on the primary shard, and if not available (failover),
299312
/// will execute on other shards.
300313
/// </para>
301314
/// </summary>
302315
public SearchDescriptor<T> ExecuteOnPrimaryFirst() => this.Preference("_primary_first");
303316

304317
/// <summary>
305318
/// <para>
306-
/// Controls a preference of which shard replicas to execute the search request on.
319+
/// Controls a preference of which shard replicas to execute the search request on.
307320
/// By default, the operation is randomized between the each shard replicas.
308321
/// </para>
309322
/// <para>
@@ -314,7 +327,7 @@ public SearchDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter>
314327

315328
/// <summary>
316329
/// <para>
317-
/// Controls a preference of which shard replicas to execute the search request on.
330+
/// Controls a preference of which shard replicas to execute the search request on.
318331
/// By default, the operation is randomized between the each shard replicas.
319332
/// </para>
320333
/// <para>
@@ -325,7 +338,7 @@ public SearchDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter>
325338

326339
/// <summary>
327340
/// <para>
328-
/// Controls a preference of which shard replicas to execute the search request on.
341+
/// Controls a preference of which shard replicas to execute the search request on.
329342
/// By default, the operation is randomized between the each shard replicas.
330343
/// </para>
331344
/// <para>
@@ -335,15 +348,15 @@ public SearchDescriptor<T> Source(Func<SourceFilterDescriptor<T>, ISourceFilter>
335348
public SearchDescriptor<T> ExecuteOnPreferredNode(string node) => this.Preference(node.IsNullOrEmpty() ? null : $"_prefer_node:{node}");
336349

337350
/// <summary>
338-
/// Allows to configure different boost level per index when searching across
351+
/// Allows to configure different boost level per index when searching across
339352
/// more than one indices. This is very handy when hits coming from one index
340353
/// matter more than hits coming from another index (think social graph where each user has an index).
341354
/// </summary>
342355
public SearchDescriptor<T> IndicesBoost(Func<FluentDictionary<IndexName, double>, FluentDictionary<IndexName, double>> boost) =>
343356
Assign(a => a.IndicesBoost = boost?.Invoke(new FluentDictionary<IndexName, double>()));
344357

345358
/// <summary>
346-
/// Allows to selectively load specific fields for each document
359+
/// Allows to selectively load specific fields for each document
347360
/// represented by a search hit. Defaults to load the internal _source field.
348361
/// </summary>
349362
public SearchDescriptor<T> Fields(Func<FieldsDescriptor<T>, IPromise<Fields>> fields) =>
@@ -363,7 +376,7 @@ public SearchDescriptor<T> ScriptFields(Func<ScriptFieldsDescriptor, IPromise<IS
363376
///</summary>
364377
public SearchDescriptor<T> Sort(Func<SortDescriptor<T>, IPromise<IList<ISort>>> selector) => Assign(a => a.Sort = selector?.Invoke(new SortDescriptor<T>())?.Value);
365378

366-
public SearchDescriptor<T> InnerHits(Func<NamedInnerHitsDescriptor<T>, IPromise<INamedInnerHits>> selector) =>
379+
public SearchDescriptor<T> InnerHits(Func<NamedInnerHitsDescriptor<T>, IPromise<INamedInnerHits>> selector) =>
367380
Assign(a => a.InnerHits = selector?.Invoke(new NamedInnerHitsDescriptor<T>())?.Value);
368381

369382
///<summary>
@@ -390,7 +403,7 @@ public SearchDescriptor<T> PostFilter(Func<QueryContainerDescriptor<T>, QueryCon
390403
Assign(a => a.PostFilter = filter.InvokeQuery(new QueryContainerDescriptor<T>()));
391404

392405
/// <summary>
393-
/// Allow to highlight search results on one or more fields. The implementation uses the either lucene fast-vector-highlighter or highlighter.
406+
/// Allow to highlight search results on one or more fields. The implementation uses the either lucene fast-vector-highlighter or highlighter.
394407
/// </summary>
395408
public SearchDescriptor<T> Highlight(Func<HighlightDescriptor<T>, IHighlight> highlightSelector) =>
396409
Assign(a => a.Highlight = highlightSelector?.Invoke(new HighlightDescriptor<T>()));
@@ -405,4 +418,4 @@ public SearchDescriptor<T> ConcreteTypeSelector(Func<dynamic, Hit<dynamic>, Type
405418
Assign(a => a.TypeSelector = typeSelector);
406419

407420
}
408-
}
421+
}

src/Nest/Search/Search/SearchResponse.cs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public interface ISearchResponse<T> : IResponse where T : class
1111
ShardsMetaData Shards { get; }
1212
HitsMetaData<T> HitsMetaData { get; }
1313
IDictionary<string, IAggregate> Aggregations { get; }
14+
Profile Profile { get; }
1415
AggregationsHelper Aggs { get; }
1516
IDictionary<string, Suggest[]> Suggest { get; }
1617
int Took { get; }
@@ -20,9 +21,9 @@ public interface ISearchResponse<T> : IResponse where T : class
2021
long Total { get; }
2122
double MaxScore { get; }
2223
/// <summary>
23-
/// Returns a view on the documents inside the hits that are returned.
24-
/// <para>NOTE: if you use Fields() on the search descriptor .Documents will be empty use
25-
/// .Fields instead or try the 'source filtering' feature introduced in Elasticsearch 1.0
24+
/// Returns a view on the documents inside the hits that are returned.
25+
/// <para>NOTE: if you use Fields() on the search descriptor .Documents will be empty use
26+
/// .Fields instead or try the 'source filtering' feature introduced in Elasticsearch 1.0
2627
/// using .Source() on the search descriptor to get Documents of type T with only certain parts selected
2728
/// </para>
2829
/// </summary>
@@ -52,7 +53,10 @@ public class SearchResponse<T> : ResponseBase, ISearchResponse<T> where T : clas
5253
[JsonProperty(PropertyName = "aggregations")]
5354
[JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter))]
5455
public IDictionary<string, IAggregate> Aggregations { get; internal set; } = new Dictionary<string, IAggregate>();
55-
56+
57+
[JsonProperty(PropertyName = "profile")]
58+
public Profile Profile { get; internal set; }
59+
5660
private AggregationsHelper _agg = null;
5761
[JsonIgnore]
5862
public AggregationsHelper Aggs => _agg ?? (_agg = new AggregationsHelper(this.Aggregations));
@@ -81,20 +85,20 @@ public class SearchResponse<T> : ResponseBase, ISearchResponse<T> where T : clas
8185
[JsonIgnore]
8286
public double MaxScore => this.HitsMetaData?.MaxScore ?? 0;
8387

84-
private IList<T> _documents;
88+
private IList<T> _documents;
8589
/// <inheritdoc/>
8690
[JsonIgnore]
87-
public IEnumerable<T> Documents =>
91+
public IEnumerable<T> Documents =>
8892
this._documents ?? (this._documents = this.Hits
8993
.Select(h => h.Source)
9094
.ToList());
9195

9296
[JsonIgnore]
9397
public IEnumerable<IHit<T>> Hits => this.HitsMetaData?.Hits ?? Enumerable.Empty<IHit<T>>();
9498

95-
private IList<FieldValues> _fields;
99+
private IList<FieldValues> _fields;
96100
/// <inheritdoc/>
97-
public IEnumerable<FieldValues> Fields =>
101+
public IEnumerable<FieldValues> Fields =>
98102
this._fields ?? (this._fields = this.Hits
99103
.Select(h => h.Fields)
100104
.ToList());
@@ -108,12 +112,12 @@ public HighlightDocumentDictionary Highlights
108112
{
109113
get
110114
{
111-
if (_highlights != null) return _highlights;
112-
115+
if (_highlights != null) return _highlights;
116+
113117
var dict = new HighlightDocumentDictionary();
114118
if (this.HitsMetaData == null || !this.HitsMetaData.Hits.HasAny())
115119
return dict;
116-
120+
117121

118122
foreach (var hit in this.HitsMetaData.Hits)
119123
{
@@ -126,4 +130,4 @@ public HighlightDocumentDictionary Highlights
126130
}
127131
}
128132
}
129-
}
133+
}

0 commit comments

Comments
 (0)