# Ordering terms aggregation

**URL:** <https://discuss.elastic.co/t/ordering-terms-aggregation/47791>\
**Category:** Elasticsearch\
**Created:** [April 19, 2016, 12:51pm UTC](https://discuss.elastic.co/t/ordering-terms-aggregation/47791 "2016-04-19T12:51:40Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![golubev](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/golubev/32/4496_2.png) [@golubev](https://discuss.elastic.co/u/golubev)\
**Post date:** [April 19, 2016, 12:51pm UTC](https://discuss.elastic.co/t/ordering-terms-aggregation/47791/1 "2016-04-19T12:51:40Z")

</div>

Hello,

We have a complicated logic of `terms` aggregation ordering and I am not able to implement using Elasticsearch.

Let's suppose that we have documents with fields `(group_id, price, x,...)`. Our goal is to:  
0. run a query that filters the whole documents set;

1. group documents by `group_id`;
2. in each group fetch the document with the highest `x` value, let's call it a "group's representative";
3. take that document's `price` and order all groups by that `price` (order groups by the `price` of theirs representatives).

Those "documents" are realty adverts exported or parsed from other sites (we are a legal aggregator) and those "groups" are groups of identical adverts posted on different sites. For each "group" we choose a representative - e.g. the most descriptive advert having photos, different characteristics etc.

Step `0` was mentioned to show that our groups change dynamically and they can have different representatives depending on the query that filters the whole document set. Those queries are any filters that our users can apply to the adverts listing, e.g. room count, appartment area, etc.

We need to show documents on our website grouped by `group_id`, each group's view is rendered using its current representative's data, groups are sorted by `price` of theirs current representatives.

I understand that step `1` is done via `terms` aggregation. Step `2` can be done using `top_hits` with sorting by `x`. But I have a problem with the step `3` implementation.

The first idea was to use the results of `top_hits` for `terms` ordering, but that is impossible (I know about `{"max": {"script": "_score"}}` workaround it is mentioned further).

The second idea was to use `scripted_metric`. I succeeded with calculation of the desired metric `representative_price` for each bucket, but when it came to ordering `terms` by it I [found it to be impossible](https://github.com/elastic/elasticsearch/issues/8486).

The third idea was to try hiding that representative's price into a document's `_score` to use [`{"max": {"script": "_score"}}` workaround](https://www.elastic.co/guide/en/elasticsearch/reference/2.3/search-aggregations-metrics-top-hits-aggregation.html#_field_collapse_example). That workaround is proposed anytime somebody asks about ordering `terms` by `top_hits` 🙂 But while trying to design such scoring function I ended up with a conclusion that such function can not be built using only document's data without knowing bucket's characteristics. As I understand that is impossible to be done using `function_score` query. I found [this research about variables available](http://stackoverflow.com/questions/30894527/script-scope-in-elasticsearch-aggregation) in the scope of Elasticsearch scripts and gave up with the third idea.

I would be thankful if anybody will propose a workaround for this issue.

---

<div class="post-metadata">

**Author:** ![golubev](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/golubev/32/4496_2.png) [@golubev](https://discuss.elastic.co/u/golubev)\
**Post date:** [April 29, 2016, 6:38pm UTC](https://discuss.elastic.co/t/ordering-terms-aggregation/47791/2 "2016-04-29T18:38:54Z")

</div>

As it happens with problems like this one, we decided to change sorting logic and group representative selection logic to simply avoid this problem 🙂

Now our `terms` aggregation will be sorted simply by `max` or `min` of appropriate fields, depending on a sort method that user would chose (e.g. price, date, etc.). The `top_hits` aggregation will choose a representative conformably to that `max` or `min` logic (e.g. for sorting `terms` by `min(price_usd)` the `top_hits` will choose the term's representative sorting docs by `{"price_usd": "asc"}` with `"size": 1`).

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 10:55pm UTC](https://discuss.elastic.co/t/ordering-terms-aggregation/47791/3 "2017-07-05T22:55:10Z")

</div>


