From b165311efef75ce7f07db8fb7d3ff10ce2cd5c42 Mon Sep 17 00:00:00 2001 From: Nick Kaltner <822124+nickkaltner@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:35:33 +1000 Subject: [PATCH] added a metrics aggregation --- lib/snap/responses/aggregation.ex | 8 ++++++-- lib/snap/responses/metrics_aggregation.ex | 19 +++++++++++++++++++ lib/snap/responses/search_response.ex | 12 +++++++++++- test/search_response_test.exs | 8 ++++---- 4 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 lib/snap/responses/metrics_aggregation.ex diff --git a/lib/snap/responses/aggregation.ex b/lib/snap/responses/aggregation.ex index 25201f2..e159cec 100644 --- a/lib/snap/responses/aggregation.ex +++ b/lib/snap/responses/aggregation.ex @@ -11,7 +11,10 @@ defmodule Snap.Aggregation do interval sum_other_doc_count value - ]a + ]a ++ + [ + type: :buckets + ] def new(response) do %__MODULE__{ @@ -30,6 +33,7 @@ defmodule Snap.Aggregation do doc_count_error_upper_bound: integer(), interval: integer(), sum_other_doc_count: integer(), - value: integer() + value: integer(), + type: atom() } end diff --git a/lib/snap/responses/metrics_aggregation.ex b/lib/snap/responses/metrics_aggregation.ex new file mode 100644 index 0000000..b0c7afb --- /dev/null +++ b/lib/snap/responses/metrics_aggregation.ex @@ -0,0 +1,19 @@ +defmodule Snap.MetricsAggregation do + @moduledoc """ + Represents an individual aggregation dictionary from a + [Search Aggregation API](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) + response. + """ + defstruct [:value, type: :metrics] + + def new(response) do + %__MODULE__{ + value: response + } + end + + @type t :: %__MODULE__{ + value: map(), + type: atom() + } +end diff --git a/lib/snap/responses/search_response.ex b/lib/snap/responses/search_response.ex index bfe9266..be8b019 100644 --- a/lib/snap/responses/search_response.ex +++ b/lib/snap/responses/search_response.ex @@ -35,7 +35,17 @@ defmodule Snap.SearchResponse do end def build_aggregations(aggregations) when is_map(aggregations) do - Map.new(aggregations, fn {key, value} -> {key, Snap.Aggregation.new(value)} end) + Map.new(aggregations, fn + {key, %{"buckets" => _} = value} -> + {key, Snap.Aggregation.new(value)} + + {key, %{"count" => _, "min" => _, "max" => _, "avg" => _, "sum" => _} = value} -> + {key, Snap.MetricsAggregation.new(value)} + + # TODO: handle other MetricsAggregations + {key, value} -> + {key, Snap.MetricsAggregation.new(value)} + end) end defimpl Enumerable do diff --git a/test/search_response_test.exs b/test/search_response_test.exs index 2cb20e5..4c0b414 100644 --- a/test/search_response_test.exs +++ b/test/search_response_test.exs @@ -53,12 +53,12 @@ defmodule Snap.SearchResponseTest do sum_other_doc_count: 0 } - assert response.aggregations["people"] == %Snap.Aggregation{ - value: 8 + assert response.aggregations["people"] == %Snap.MetricsAggregation{ + value: %{"value" => 8} } - assert response.aggregations["things"] == %Snap.Aggregation{ - doc_count: 9 + assert response.aggregations["things"] == %Snap.MetricsAggregation{ + value: %{"doc_count" => 9} } assert response.aggregations["histogram"] == %Snap.Aggregation{