Scripted Metric Aggregation Usageedit

Fluent DSL exampleedit

a => a
.ScriptedMetric("sum_the_hard_way", sm => sm
    .InitScript(ss => ss.Source(_script.Init))
    .MapScript(ss => ss.Source(_script.Map))
    .CombineScript(ss => ss.Source(_script.Combine))
    .ReduceScript(ss => ss.Source(_script.Reduce))
)

Object Initializer syntax exampleedit

new ScriptedMetricAggregation("sum_the_hard_way")
{
    InitScript = new InlineScript(_script.Init),
    MapScript = new InlineScript(_script.Map),
    CombineScript = new InlineScript(_script.Combine),
    ReduceScript = new InlineScript(_script.Reduce)
}

Example json output. 

{
  "sum_the_hard_way": {
    "scripted_metric": {
      "init_script": {
        "source": "state.commits = []"
      },
      "map_script": {
        "source": "if (doc['state'].value == \"Stable\") { state.commits.add(doc['numberOfCommits'].value) }"
      },
      "combine_script": {
        "source": "def sum = 0.0; for (c in state.commits) { sum += c } return sum"
      },
      "reduce_script": {
        "source": "def sum = 0.0; for (a in states) { sum += a } return sum"
      }
    }
  }
}

Handling Responsesedit

response.ShouldBeValid();
var sumTheHardWay = response.Aggregations.ScriptedMetric("sum_the_hard_way");
sumTheHardWay.Should().NotBeNull();
sumTheHardWay.Value<int>().Should().BeGreaterThan(0);
private class Scripted
{
    public string Combine { get; set; }
    public string Init { get; set; }
    // ReSharper disable once UnusedAutoPropertyAccessor.Local
    public string Language { get; set; }
    public string Map { get; set; }
    public string Reduce { get; set; }
}

Fluent DSL exampleedit

a => a
.ScriptedMetric("by_state_total", sm => sm
    .InitScript(ss => ss.Source(_first.Init).Lang(_first.Language))
    .CombineScript(ss => ss.Source(_first.Combine).Lang(_first.Language))
    .MapScript(ss => ss.Source(_first.Map).Lang(_first.Language))
    .ReduceScript(ss => ss.Source(_first.Reduce).Lang(_first.Language))
)
.ScriptedMetric("total_commits", sm => sm
    .InitScript(ss => ss.Source(_second.Init).Lang(_second.Language))
    .MapScript(ss => ss.Source(_second.Map).Lang(_second.Language))
    .CombineScript(ss => ss.Source(_second.Combine).Lang(_second.Language))
    .ReduceScript(ss => ss.Source(_second.Reduce).Lang(_second.Language))
)

Object Initializer syntax exampleedit

new ScriptedMetricAggregation("by_state_total")
{
    InitScript = new InlineScript(_first.Init) { Lang = _first.Language },
    CombineScript = new InlineScript(_first.Combine) { Lang = _first.Language },
    MapScript = new InlineScript(_first.Map) { Lang = _first.Language },
    ReduceScript = new InlineScript(_first.Reduce) { Lang = _first.Language }
}
&& new ScriptedMetricAggregation("total_commits")
{
    InitScript = new InlineScript(_second.Init) { Lang = _second.Language },
    MapScript = new InlineScript(_second.Map) { Lang = _second.Language },
    CombineScript = new InlineScript(_second.Combine) { Lang = _second.Language },
    ReduceScript = new InlineScript(_second.Reduce) { Lang = _second.Language }
}

Example json output. 

{
  "by_state_total": {
    "scripted_metric": {
      "init_script": {
        "source": "state.map = [:]",
        "lang": "painless"
      },
      "combine_script": {
        "source": "return state.map;",
        "lang": "painless"
      },
      "map_script": {
        "source": "if (state.map.containsKey(doc['state'].value)) state.map[doc['state'].value] += 1; else state.map[doc['state'].value] = 1;",
        "lang": "painless"
      },
      "reduce_script": {
        "source": "def reduce = [:]; for (map in states){ for (entry in map.entrySet()) { if (reduce.containsKey(entry.getKey())) reduce[entry.getKey()] += entry.getValue(); else reduce[entry.getKey()] = entry.getValue(); }} return reduce;",
        "lang": "painless"
      }
    }
  },
  "total_commits": {
    "scripted_metric": {
      "init_script": {
        "source": "state.commits = []",
        "lang": "painless"
      },
      "map_script": {
        "source": "if (doc['state'].value == \"Stable\") { state.commits.add(doc['numberOfCommits'].value) }",
        "lang": "painless"
      },
      "combine_script": {
        "source": "def sum = 0.0; for (c in state.commits) { sum += c } return sum",
        "lang": "painless"
      },
      "reduce_script": {
        "source": "def sum = 0.0; for (a in states) { sum += a } return sum",
        "lang": "painless"
      }
    }
  }
}

Handling Responsesedit

response.ShouldBeValid();
var byStateTotal = response.Aggregations.ScriptedMetric("by_state_total");
var totalCommits = response.Aggregations.ScriptedMetric("total_commits");

byStateTotal.Should().NotBeNull();
totalCommits.Should().NotBeNull();

byStateTotal.Value<IDictionary<string, int>>().Should().NotBeNull();
totalCommits.Value<int>().Should().BeGreaterThan(0);