Skip to content

Commit d4cf9e7

Browse files
committed
Merge pull request #1135 from elasticsearch/feature/aggs-scriptedmetric
Scripted metric aggregation support
2 parents 7c4a988 + 6a7695a commit d4cf9e7

File tree

9 files changed

+411
-7
lines changed

9 files changed

+411
-7
lines changed

src/Nest/DSL/Aggregations/AggregationDescriptor.cs

+19-1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ public interface IAggregationContainer
9090
[JsonProperty("top_hits")]
9191
ITopHitsAggregator TopHits { get; set; }
9292

93+
[JsonProperty("scripted_metric")]
94+
IScriptedMetricAggregator ScriptedMetric { get; set; }
95+
9396
[JsonProperty("aggs")]
9497
[JsonConverter(typeof(DictionaryKeysAreNotPropertyNamesJsonConverter))]
9598
IDictionary<string, IAggregationContainer> Aggregations { get; set; }
@@ -117,8 +120,9 @@ public class AggregationContainer : IAggregationContainer
117120
private ISignificantTermsAggregator _significantTerms;
118121
private IPercentileRanksAggregaor _percentileRanks;
119122
private IFiltersAggregator _filters;
120-
121123
private ITopHitsAggregator _topHits;
124+
private IScriptedMetricAggregator _scriptedMetric;
125+
122126
public IAverageAggregator Average { get; set; }
123127
public IValueCountAggregator ValueCount { get; set; }
124128
public IMaxAggregator Max { get; set; }
@@ -246,6 +250,12 @@ public ITopHitsAggregator TopHits
246250
set { _topHits = value; }
247251
}
248252

253+
public IScriptedMetricAggregator ScriptedMetric
254+
{
255+
get { return _scriptedMetric; }
256+
set { _scriptedMetric = value; }
257+
}
258+
249259
private void LiftAggregations(IBucketAggregator bucket)
250260
{
251261
if (bucket == null) return;
@@ -314,6 +324,8 @@ public class AggregationDescriptor<T> : IAggregationContainer
314324

315325
ITopHitsAggregator IAggregationContainer.TopHits { get; set; }
316326

327+
IScriptedMetricAggregator IAggregationContainer.ScriptedMetric { get; set; }
328+
317329
public AggregationDescriptor<T> Average(string name, Func<AverageAggregationDescriptor<T>, AverageAggregationDescriptor<T>> selector)
318330
{
319331
return _SetInnerAggregation(name, selector, (a, d) => a.Average = d);
@@ -464,6 +476,12 @@ public AggregationDescriptor<T> TopHits(string name,
464476
return _SetInnerAggregation(name, selector, (a, d) => a.TopHits = d);
465477
}
466478

479+
public AggregationDescriptor<T> ScriptedMetric(string name,
480+
Func<ScriptedMetricAggregationDescriptor<T>, ScriptedMetricAggregationDescriptor<T>> selector)
481+
{
482+
return _SetInnerAggregation(name, selector, (a, d) => a.ScriptedMetric = d);
483+
}
484+
467485
private AggregationDescriptor<T> _SetInnerAggregation<TAggregation>(
468486
string key,
469487
Func<TAggregation, TAggregation> selector
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
using Nest.Resolvers.Converters;
2+
using Newtonsoft.Json;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
8+
namespace Nest
9+
{
10+
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
11+
[JsonConverter(typeof(ReadAsTypeConverter<ScriptedMetricsAggregator>))]
12+
public interface IScriptedMetricAggregator
13+
{
14+
[JsonProperty("init_script")]
15+
string InitScript { get; set; }
16+
17+
[JsonProperty("init_script_file")]
18+
string InitScriptFile { get; set; }
19+
20+
[JsonProperty("init_script_id")]
21+
string InitScriptId { get; set; }
22+
23+
[JsonProperty("map_script")]
24+
string MapScript { get; set; }
25+
26+
[JsonProperty("map_script_file")]
27+
string MapScriptFile { get; set; }
28+
29+
[JsonProperty("map_script_id")]
30+
string MapScriptId { get; set; }
31+
32+
[JsonProperty("combine_script")]
33+
string CombineScript { get; set; }
34+
35+
[JsonProperty("combine_script_file")]
36+
string CombineScriptFile { get; set; }
37+
38+
[JsonProperty("combine_script_id")]
39+
string CombineScriptId { get; set; }
40+
41+
[JsonProperty("reduce_script")]
42+
string ReduceScript { get; set; }
43+
44+
[JsonProperty("reduce_script_file")]
45+
string ReduceScriptFile { get; set; }
46+
47+
[JsonProperty("reduce_script_id")]
48+
string ReduceScriptId { get; set; }
49+
50+
[JsonProperty("reduce_params")]
51+
IDictionary<string, object> ReduceParams { get; set; }
52+
}
53+
54+
public class ScriptedMetricsAggregator : MetricAggregator, IScriptedMetricAggregator
55+
{
56+
public string InitScript { get; set; }
57+
public string InitScriptFile { get; set; }
58+
public string InitScriptId { get; set; }
59+
public string MapScript { get; set; }
60+
public string MapScriptFile { get; set; }
61+
public string MapScriptId { get; set; }
62+
public string CombineScript { get; set; }
63+
public string CombineScriptFile { get; set; }
64+
public string CombineScriptId { get; set; }
65+
public string ReduceScript { get; set; }
66+
public string ReduceScriptFile { get; set; }
67+
public string ReduceScriptId { get; set; }
68+
public IDictionary<string, object> ReduceParams { get; set; }
69+
}
70+
71+
public class ScriptedMetricAggregationDescriptor<T>
72+
: MetricAggregationBaseDescriptor<ScriptedMetricAggregationDescriptor<T>, T>, IScriptedMetricAggregator
73+
where T : class
74+
{
75+
IScriptedMetricAggregator Self { get { return this; } }
76+
77+
string IScriptedMetricAggregator.InitScript { get; set; }
78+
string IScriptedMetricAggregator.InitScriptFile { get; set; }
79+
string IScriptedMetricAggregator.InitScriptId { get; set; }
80+
string IScriptedMetricAggregator.MapScript { get; set; }
81+
string IScriptedMetricAggregator.MapScriptFile { get; set; }
82+
string IScriptedMetricAggregator.MapScriptId { get; set; }
83+
string IScriptedMetricAggregator.CombineScript { get; set; }
84+
string IScriptedMetricAggregator.CombineScriptFile { get; set; }
85+
string IScriptedMetricAggregator.CombineScriptId { get; set; }
86+
string IScriptedMetricAggregator.ReduceScript { get; set; }
87+
string IScriptedMetricAggregator.ReduceScriptFile { get; set; }
88+
string IScriptedMetricAggregator.ReduceScriptId { get; set; }
89+
IDictionary<string, object> IScriptedMetricAggregator.ReduceParams { get; set; }
90+
91+
public ScriptedMetricAggregationDescriptor<T> InitScript(string script)
92+
{
93+
this.Self.InitScript = script;
94+
return this;
95+
}
96+
97+
public ScriptedMetricAggregationDescriptor<T> InitScriptFile(string file)
98+
{
99+
this.Self.InitScriptFile = file;
100+
return this;
101+
}
102+
103+
public ScriptedMetricAggregationDescriptor<T> InitScriptId(string id)
104+
{
105+
this.Self.InitScriptId = id;
106+
return this;
107+
}
108+
109+
public ScriptedMetricAggregationDescriptor<T> MapScript(string script)
110+
{
111+
this.Self.MapScript = script;
112+
return this;
113+
}
114+
115+
public ScriptedMetricAggregationDescriptor<T> MapScriptFile(string file)
116+
{
117+
this.Self.MapScriptFile = file;
118+
return this;
119+
}
120+
121+
public ScriptedMetricAggregationDescriptor<T> MapScriptId(string id)
122+
{
123+
this.Self.MapScriptId = id;
124+
return this;
125+
}
126+
127+
public ScriptedMetricAggregationDescriptor<T> CombineScript(string script)
128+
{
129+
this.Self.CombineScript = script;
130+
return this;
131+
}
132+
133+
public ScriptedMetricAggregationDescriptor<T> CombineScriptFile(string file)
134+
{
135+
this.Self.CombineScriptFile = file;
136+
return this;
137+
}
138+
139+
public ScriptedMetricAggregationDescriptor<T> CombineScriptId(string id)
140+
{
141+
this.Self.CombineScriptId = id;
142+
return this;
143+
}
144+
145+
public ScriptedMetricAggregationDescriptor<T> ReduceScript(string script)
146+
{
147+
this.Self.ReduceScript = script;
148+
return this;
149+
}
150+
151+
public ScriptedMetricAggregationDescriptor<T> ReduceScriptFile(string file)
152+
{
153+
this.Self.ReduceScriptFile = file;
154+
return this;
155+
}
156+
157+
public ScriptedMetricAggregationDescriptor<T> ReduceScriptId(string id)
158+
{
159+
this.Self.ReduceScriptId = id;
160+
return this;
161+
}
162+
163+
public ScriptedMetricAggregationDescriptor<T> ReduceParams(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> paramSelector)
164+
{
165+
this.Self.ReduceParams = paramSelector(new FluentDictionary<string, object>());
166+
return this;
167+
}
168+
}
169+
}

src/Nest/Domain/Aggregations/AggregationsHelper.cs

+12
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ public ValueMetric ValueCount(string key)
5555
return this.TryGet<ValueMetric>(key);
5656
}
5757

58+
public ScriptedValueMetric ScriptedMetric(string key)
59+
{
60+
var valueMetric = this.TryGet<ValueMetric>(key);
61+
62+
if (valueMetric != null)
63+
{
64+
return new ScriptedValueMetric { _Value = valueMetric.Value };
65+
}
66+
67+
return this.TryGet<ScriptedValueMetric>(key);
68+
}
69+
5870
public StatsMetric Stats(string key)
5971
{
6072
return this.TryGet<StatsMetric>(key);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+

2+
using Newtonsoft.Json.Linq;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
8+
namespace Nest
9+
{
10+
public class ScriptedValueMetric : IMetricAggregation
11+
{
12+
internal object _Value { get; set; }
13+
14+
/// <summary>
15+
/// Get the resut of the scripted metric aggregation as T
16+
/// </summary>
17+
/// <typeparam name="T">The type that best represents the result of your scripted metric aggrgation</typeparam>
18+
public T Value<T>()
19+
{
20+
var jToken = this._Value as JToken;
21+
22+
if (jToken != null)
23+
return jToken.ToObject<T>();
24+
25+
return (T)this._Value;
26+
}
27+
}
28+
}

src/Nest/Nest.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
<Compile Include="Domain\Aggregations\Bucket.cs" />
110110
<Compile Include="Domain\Aggregations\BucketAggregationBase.cs" />
111111
<Compile Include="Domain\Aggregations\FiltersBucket.cs" />
112+
<Compile Include="Domain\Aggregations\ScriptedValueMetric.cs" />
112113
<Compile Include="Domain\Aggregations\TopHitsMetric.cs" />
113114
<Compile Include="Domain\Aggregations\GeoBoundsMetric.cs" />
114115
<Compile Include="Domain\Aggregations\HistogramItem.cs" />
@@ -233,6 +234,7 @@
233234
<Compile Include="Domain\Suggest\SuggestField.cs" />
234235
<Compile Include="DSL\Aggregations\FiltersAggregationDescriptor.cs" />
235236
<Compile Include="DSL\Aggregations\PercentileRanksAggregationDescriptor.cs" />
237+
<Compile Include="DSL\Aggregations\ScriptedMetricAggregationDescriptor.cs" />
236238
<Compile Include="DSL\Aggregations\TopHitsAggregationDescriptor.cs" />
237239
<Compile Include="DSL\Aggregations\GeoBoundsAggregationDescriptor.cs" />
238240
<Compile Include="DSL\Aggregations\ReverseNestedAggregationDescriptor.cs" />

src/Nest/Resolvers/Converters/Aggregations/AggregationConverter.cs

+16-5
Original file line numberDiff line numberDiff line change
@@ -351,14 +351,25 @@ private IAggregation GetBucketAggregation(JsonReader reader, JsonSerializer seri
351351
private IAggregation GetValueMetricOrAggregation(JsonReader reader, JsonSerializer serializer)
352352
{
353353
reader.Read();
354-
var metric = new ValueMetric()
354+
var valueMetric = new ValueMetric()
355355
{
356356
Value = (reader.Value as double?)
357357
};
358-
if (metric.Value == null && reader.ValueType == typeof(long))
359-
metric.Value = reader.Value as long?;
360-
reader.Read();
361-
return metric;
358+
if (valueMetric.Value == null && reader.ValueType == typeof(long))
359+
valueMetric.Value = reader.Value as long?;
360+
361+
if (valueMetric.Value != null)
362+
{
363+
reader.Read();
364+
return valueMetric;
365+
}
366+
367+
var scriptedMetric = serializer.Deserialize(reader);
368+
369+
if (scriptedMetric != null)
370+
return new ScriptedValueMetric { _Value = scriptedMetric };
371+
372+
return valueMetric;
362373
}
363374

364375
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)

0 commit comments

Comments
 (0)