Skip to content

Commit 4917664

Browse files
committed
Fix/muliple scripted metric aggs (#2761)
* added failing test that uses two adjacent scripted metric aggs * multiple adjecent scripted metrics are not read correctly Conflicts: src/Tests/Aggregations/Metric/ScriptedMetric/ScriptedMetricAggregationUsageTests.cs
1 parent 9662b1f commit 4917664

File tree

2 files changed

+173
-13
lines changed

2 files changed

+173
-13
lines changed

src/Nest/Aggregations/AggregateJsonConverter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,10 +542,11 @@ private IAggregate GetValueAggregate(JsonReader reader, JsonSerializer serialize
542542

543543
var scriptedMetric = serializer.Deserialize(reader);
544544

545+
546+
reader.Read();
545547
if (scriptedMetric != null)
546548
return new ScriptedMetricAggregate { _Value = scriptedMetric };
547549

548-
reader.Read();
549550
return valueMetric;
550551
}
551552

src/Tests/Aggregations/Metric/ScriptedMetric/ScriptedMetricAggregationUsageTests.cs

Lines changed: 171 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
using Tests.Framework.Integration;
66
using Tests.Framework.ManagedElasticsearch.Clusters;
77
using Tests.Framework.MockData;
8+
using System.Collections.Generic;
89

910
namespace Tests.Aggregations.Metric.ScriptedMetric
1011
{
1112
public class ScriptedMetricAggregationUsageTests : AggregationUsageTestBase
1213
{
13-
public ScriptedMetricAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage) { }
14+
public ScriptedMetricAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage)
15+
{
16+
}
1417

1518
protected override object ExpectJson => new
1619
{
@@ -23,18 +26,22 @@ public ScriptedMetricAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usag
2326
init_script = new
2427
{
2528
inline = "_agg['commits'] = []",
29+
lang = "groovy"
2630
},
2731
map_script = new
2832
{
29-
inline = "if (doc['state'].value == \"Stable\") { _agg.commits.add(doc['numberOfCommits']) }"
33+
inline = "if (doc['state'].value == \"Stable\") { _agg.commits.add(doc['numberOfCommits']) }",
34+
lang = "groovy"
3035
},
3136
combine_script = new
3237
{
33-
inline = "sum = 0; for (c in _agg.commits) { sum += c }; return sum"
38+
inline = "sum = 0; for (c in _agg.commits) { sum += c }; return sum",
39+
lang = "groovy"
3440
},
3541
reduce_script = new
3642
{
37-
inline = "sum = 0; for (a in _aggs) { sum += a }; return sum"
43+
inline = "sum = 0; for (a in _aggs) { sum += a }; return sum",
44+
lang = "groovy"
3845
}
3946
}
4047
}
@@ -44,10 +51,10 @@ public ScriptedMetricAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usag
4451
protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent => s => s
4552
.Aggregations(a => a
4653
.ScriptedMetric("sum_the_hard_way", sm => sm
47-
.InitScript("_agg['commits'] = []")
48-
.MapScript("if (doc['state'].value == \"Stable\") { _agg.commits.add(doc['numberOfCommits']) }")
49-
.CombineScript("sum = 0; for (c in _agg.commits) { sum += c }; return sum")
50-
.ReduceScript("sum = 0; for (a in _aggs) { sum += a }; return sum")
54+
.InitScript(ss => ss.Inline("_agg['commits'] = []").Lang("groovy"))
55+
.MapScript(ss => ss.Inline("if (doc['state'].value == \"Stable\") { _agg.commits.add(doc['numberOfCommits']) }").Lang("groovy"))
56+
.CombineScript(ss => ss.Inline("sum = 0; for (c in _agg.commits) { sum += c }; return sum").Lang("groovy"))
57+
.ReduceScript(ss => ss.Inline("sum = 0; for (a in _aggs) { sum += a }; return sum").Lang("groovy"))
5158
)
5259
);
5360

@@ -56,10 +63,10 @@ public ScriptedMetricAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usag
5663
{
5764
Aggregations = new ScriptedMetricAggregation("sum_the_hard_way")
5865
{
59-
InitScript = new InlineScript("_agg['commits'] = []"),
60-
MapScript = new InlineScript("if (doc['state'].value == \"Stable\") { _agg.commits.add(doc['numberOfCommits']) }"),
61-
CombineScript = new InlineScript("sum = 0; for (c in _agg.commits) { sum += c }; return sum"),
62-
ReduceScript = new InlineScript("sum = 0; for (a in _aggs) { sum += a }; return sum")
66+
InitScript = new InlineScript("_agg['commits'] = []") {Lang = "groovy"},
67+
MapScript = new InlineScript("if (doc['state'].value == \"Stable\") { _agg.commits.add(doc['numberOfCommits']) }") {Lang = "groovy"},
68+
CombineScript = new InlineScript("sum = 0; for (c in _agg.commits) { sum += c }; return sum") {Lang = "groovy"},
69+
ReduceScript = new InlineScript("sum = 0; for (a in _aggs) { sum += a }; return sum") {Lang = "groovy"}
6370
}
6471
};
6572

@@ -71,4 +78,156 @@ protected override void ExpectResponse(ISearchResponse<Project> response)
7178
sumTheHardWay.Value<int>().Should().BeGreaterThan(0);
7279
}
7380
}
81+
82+
/// <summary>
83+
/// Multiple scripted metric with dictionary result
84+
/// </summary>
85+
public class ScriptedMetricMultiAggregationTests : AggregationUsageTestBase
86+
{
87+
class Scripted
88+
{
89+
public string Language { get; set; }
90+
public string Combine { get; set; }
91+
public string Reduce { get; set; }
92+
public string Map { get; set; }
93+
public string Init { get; set; }
94+
}
95+
96+
private Scripted First = new Scripted
97+
{
98+
Language = "painless",
99+
Init = "params._agg.map = [:]",
100+
Map =
101+
"if (params._agg.map.containsKey(doc['state'].value))" +
102+
" params._agg.map[doc['state'].value] += 1;" +
103+
"else" +
104+
" params._agg.map[doc['state'].value] = 1;",
105+
106+
Reduce =
107+
"def reduce = [:];" +
108+
"for (agg in params._aggs)" +
109+
"{" +
110+
" for (entry in agg.map.entrySet())" +
111+
" {" +
112+
" if (reduce.containsKey(entry.getKey()))" +
113+
" reduce[entry.getKey()] += entry.getValue();" +
114+
" else" +
115+
" reduce[entry.getKey()] = entry.getValue();" +
116+
" }" +
117+
"}" +
118+
"return reduce;"
119+
};
120+
121+
private Scripted Second = new Scripted
122+
{
123+
Language = "painless",
124+
Combine = "def sum = 0.0; for (c in params._agg.commits) { sum += c } return sum",
125+
Reduce = "def sum = 0.0; for (a in params._aggs) { sum += a } return sum",
126+
Map = "if (doc['state'].value == \"Stable\") { params._agg.commits.add(doc['numberOfCommits'].value) }",
127+
Init = "params._agg.commits = []"
128+
};
129+
130+
public ScriptedMetricMultiAggregationTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage) { }
131+
132+
protected override object ExpectJson => new
133+
{
134+
aggs = new
135+
{
136+
by_state_total = new
137+
{
138+
scripted_metric = new
139+
{
140+
init_script = new
141+
{
142+
inline = First.Init,
143+
lang = First.Language
144+
},
145+
map_script = new
146+
{
147+
inline = First.Map,
148+
lang = First.Language
149+
},
150+
reduce_script = new
151+
{
152+
inline = First.Reduce,
153+
lang = First.Language
154+
}
155+
}
156+
},
157+
total_commits = new
158+
{
159+
scripted_metric = new
160+
{
161+
init_script = new
162+
{
163+
inline = Second.Init,
164+
lang = Second.Language
165+
},
166+
map_script = new
167+
{
168+
inline = Second.Map,
169+
lang = Second.Language
170+
},
171+
combine_script = new
172+
{
173+
inline = Second.Combine,
174+
lang = Second.Language
175+
},
176+
reduce_script = new
177+
{
178+
inline = Second.Reduce,
179+
lang = Second.Language
180+
}
181+
}
182+
}
183+
}
184+
};
185+
186+
protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent => s => s
187+
.Aggregations(a => a
188+
.ScriptedMetric("by_state_total", sm => sm
189+
.InitScript(ss => ss.Inline(First.Init).Lang(First.Language))
190+
.MapScript(ss => ss.Inline(First.Map).Lang(First.Language))
191+
.ReduceScript(ss => ss.Inline(First.Reduce).Lang(First.Language))
192+
)
193+
.ScriptedMetric("total_commits", sm => sm
194+
.InitScript(ss => ss.Inline(Second.Init).Lang(Second.Language))
195+
.MapScript(ss => ss.Inline(Second.Map).Lang(Second.Language))
196+
.CombineScript(ss => ss.Inline(Second.Combine).Lang(Second.Language))
197+
.ReduceScript(ss => ss.Inline(Second.Reduce).Lang(Second.Language))
198+
)
199+
);
200+
201+
protected override SearchRequest<Project> Initializer =>
202+
new SearchRequest<Project>
203+
{
204+
Aggregations =
205+
new ScriptedMetricAggregation("by_state_total")
206+
{
207+
InitScript = new InlineScript(First.Init) {Lang = First.Language},
208+
MapScript = new InlineScript(First.Map) {Lang = First.Language},
209+
ReduceScript = new InlineScript(First.Reduce) {Lang = First.Language}
210+
} &&
211+
new ScriptedMetricAggregation("total_commits")
212+
{
213+
InitScript = new InlineScript(Second.Init) {Lang = Second.Language},
214+
MapScript = new InlineScript(Second.Map) {Lang = Second.Language},
215+
CombineScript = new InlineScript(Second.Combine) {Lang = Second.Language},
216+
ReduceScript = new InlineScript(Second.Reduce) {Lang = Second.Language}
217+
}
218+
};
219+
220+
protected override void ExpectResponse(ISearchResponse<Project> response)
221+
{
222+
response.ShouldBeValid();
223+
var by_state_total = response.Aggs.ScriptedMetric("by_state_total");
224+
var total_commits = response.Aggs.ScriptedMetric("total_commits");
225+
226+
by_state_total.Should().NotBeNull();
227+
total_commits.Should().NotBeNull();
228+
229+
by_state_total.Value<IDictionary<string, int>>().Should().NotBeNull();
230+
total_commits.Value<int>().Should().BeGreaterThan(0);
231+
}
232+
}
74233
}

0 commit comments

Comments
 (0)