diff --git a/pybana/translators/elastic/__init__.py b/pybana/translators/elastic/__init__.py index af76bf5..468bcf1 100644 --- a/pybana/translators/elastic/__init__.py +++ b/pybana/translators/elastic/__init__.py @@ -10,9 +10,22 @@ from .filter import FilterTranslator from .utils import SearchListProxy + __all__ = ("ElasticTranslator", "FilterTranslator") +class SignificantTerms(elasticsearch_dsl.query.Terms): + name = "significant_terms" + + +class TopMetrics(elasticsearch_dsl.aggs.TopHits): + name = "top_metrics" + + +elasticsearch_dsl.query.Query._classes[SignificantTerms.name] = SignificantTerms +elasticsearch_dsl.aggs.Agg._classes[TopMetrics.name] = TopMetrics + + class ElasticTranslator: def __init__(self, using): self._using = using diff --git a/pybana/translators/elastic/buckets.py b/pybana/translators/elastic/buckets.py index 2fbd755..6128781 100644 --- a/pybana/translators/elastic/buckets.py +++ b/pybana/translators/elastic/buckets.py @@ -160,9 +160,7 @@ def translate(self, agg, state, context, field): } -class TermsBucket(BaseBucket): - aggtype = "terms" - +class BaseTermsBucket(BaseBucket): def translate(self, agg, state, context, field): orderby = agg["params"]["orderBy"] aggs = {agg["id"]: agg for agg in state["aggs"]} @@ -178,6 +176,20 @@ def translate(self, agg, state, context, field): } +class TermsBucket(BaseBucket): + aggtype = "terms" + + +class SignificantTermsBucket(BaseBucket): + aggtype = "significant_terms" + + def translate(self, agg, state, context, field): + ret = agg["params"] + if field and field.get("scripted"): + ret["valueType"] = field["type"] + return ret + + TRANSLATORS = { translator.aggtype: translator for translator in ( @@ -187,6 +199,7 @@ def translate(self, agg, state, context, field): HistogramBucket, RangeBucket, TermsBucket, + SignificantTermsBucket, ) } diff --git a/pybana/translators/elastic/metrics.py b/pybana/translators/elastic/metrics.py index 205d74f..e305518 100644 --- a/pybana/translators/elastic/metrics.py +++ b/pybana/translators/elastic/metrics.py @@ -131,13 +131,35 @@ def translate(self, proxy, agg, state, field): params = agg["params"] proxy.metric( agg["id"], - "top_hits", + self.aggtype, sort={params["sortField"]: {"order": params["sortOrder"]}}, size=params["size"], _source=agg["params"]["field"], ) +class TopMetricsMetric(BaseMetric): + """ + Translator for top_metrics metric. + + Careful, this metric is partially supported: + - date fields are not handled. + - scripted fields are not handled. + """ + + aggtype = "top_metrics" + + def translate(self, proxy, agg, state, field): + params = agg["params"] + proxy.metric( + agg["id"], + self.aggtype, + sort={params["sortField"]: {"order": params["sortOrder"]}}, + size=params["size"], + metrics={"field": agg["params"]["field"]}, + ) + + TRANSLATORS = { translator.aggtype: translator for translator in ( @@ -153,6 +175,7 @@ def translate(self, proxy, agg, state, field): StdDevMetric, SumMetric, TopHitsMetric, + TopMetricsMetric, ) } diff --git a/pybana/translators/vega/metrics.py b/pybana/translators/vega/metrics.py index 0b93cc8..c259842 100644 --- a/pybana/translators/vega/metrics.py +++ b/pybana/translators/vega/metrics.py @@ -109,6 +109,23 @@ def flatten(value): return ", ".join(map(str, values)) +class TopMetricsMetric(BaseMetric): + """ + Metric for top_metrics. + """ + + aggtype = "top_metrics" + + def contribute(self, agg, bucket, response): + hit = bucket[agg["id"]]["top"][0] + value = ( + hit["metrics"][agg["params"]["field"]] + if agg["params"]["field"] in hit["metrics"] + else None + ) + return value + + VEGA_METRICS = { metric.aggtype: metric for metric in [ @@ -122,5 +139,6 @@ def flatten(value): StdDevMetric, SumMetric, TopHitsMetric, + TopMetricsMetric, ] }