# Group and filter results

**URL:** <https://discuss.elastic.co/t/group-and-filter-results/55775>\
**Category:** Elasticsearch\
**Created:** [July 18, 2016, 3:09pm UTC](https://discuss.elastic.co/t/group-and-filter-results/55775 "2016-07-18T15:09:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![PhilippC](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/philippc/32/7337_2.png) [@PhilippC](https://discuss.elastic.co/u/PhilippC)\
**Post date:** [July 18, 2016, 3:09pm UTC](https://discuss.elastic.co/t/group-and-filter-results/55775/1 "2016-07-18T15:09:40Z")

</div>

I have an index of DocumentVersions - different versions of a document.

```
{versionId: 1, documentId:1, ...},
{versionId: 2, documentId:1, ...},
{versionId: 3, documentId:2, ...},
{versionId: 4, documentId:2, ...},
...

```

By default users should only receive the **most recent version of a document**.

In **Solr** i used **ResultGrouping** : `group.field=documentId, group.limit=1, group.sort=versionId desc`.

How can i achieve something similar with elasticsearch?

_I tried "top-hits-aggregation" (bucket for documentId, order by versionId desc and size 1). That worked, but i ran into problems with paging as for example size effects number of documents, not number of buckets_

---

<div class="post-metadata">

**Author:** ![mikemccand](https://avatars.discourse-cdn.com/v4/letter/m/f04885/32.png) [@mikemccand](https://discuss.elastic.co/u/mikemccand)\
**Post date:** [July 18, 2016, 3:44pm UTC](https://discuss.elastic.co/t/group-and-filter-results/55775/2 "2016-07-18T15:44:14Z")

</div>

Maybe using terms aggregation (on your `documentId` field), with `top_hits` sub-aggregation?

---

<div class="post-metadata">

**Author:** ![PhilippC](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/philippc/32/7337_2.png) [@PhilippC](https://discuss.elastic.co/u/PhilippC)\
**Post date:** [July 18, 2016, 5:12pm UTC](https://discuss.elastic.co/t/group-and-filter-results/55775/3 "2016-07-18T17:12:50Z")

</div>

Thank you for your tip, but thats what i wrote i already tried.  
=\> ran into problems with paging.

---

<div class="post-metadata">

**Author:** ![mikemccand](https://avatars.discourse-cdn.com/v4/letter/m/f04885/32.png) [@mikemccand](https://discuss.elastic.co/u/mikemccand)\
**Post date:** [July 18, 2016, 6:04pm UTC](https://discuss.elastic.co/t/group-and-filter-results/55775/4 "2016-07-18T18:04:51Z")

</div>

Woops, sorry, I missed that you had already tried this.

But: `size` should control the number of buckets ... not sure why you're seeing otherwise.

You could maybe try parent/child documents instead? Index a parent document for each unique `documentId`, and then one child document for each `versionId`. [https://www.elastic.co/guide/en/elasticsearch/guide/current/parent-child.html](https://www.elastic.co/guide/en/elasticsearch/guide/current/parent-child.html)

---

<div class="post-metadata">

**Author:** ![PhilippC](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/philippc/32/7337_2.png) [@PhilippC](https://discuss.elastic.co/u/PhilippC)\
**Post date:** [July 18, 2016, 7:09pm UTC](https://discuss.elastic.co/t/group-and-filter-results/55775/5 "2016-07-18T19:09:09Z")

</div>

Documentation says: "_[...] size - The maximum number of top matching hits to return per bucket.[...]_"

Your parent/child hint is interesting. I did not know about that yet.  
But how would a grouping query look like if i model my data that way?

Lets say a query matches multiple versions(children) of a multiple documents(parents).  
How would i make sure only the most recent versions are returned?

---

<div class="post-metadata">

**Author:** ![mikemccand](https://avatars.discourse-cdn.com/v4/letter/m/f04885/32.png) [@mikemccand](https://discuss.elastic.co/u/mikemccand)\
**Post date:** [July 18, 2016, 8:02pm UTC](https://discuss.elastic.co/t/group-and-filter-results/55775/6 "2016-07-18T20:02:30Z")

</div>

Oh, I see: I was talking about the `size` parameter for the terms aggregation: [https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html)

That should let you control how many unique `documentId` you get back?

Whereas the size parameter to the `top_hits` sub aggregation says how many top documents to keep in each bucket.

Using parent/child, I think you could sort on `versionId`? But, that probably won't work for you in general, i.e. you typically would want to sort on relevance or something else that's child-specific? Do you really need to keep the old child versions around?

---

<div class="post-metadata">

**Author:** ![PhilippC](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/philippc/32/7337_2.png) [@PhilippC](https://discuss.elastic.co/u/PhilippC)\
**Post date:** [July 19, 2016, 9:46am UTC](https://discuss.elastic.co/t/group-and-filter-results/55775/7 "2016-07-19T09:46:21Z")

</div>

You are right. By setting size for the terms aggregation i can control how many documents (unique `documenId`) i get back. But that way i loose the number of TotalHits.

I somehow need to "rewrite the aggregation" to a standard result.

- TotalHits should represent the number of documents (unique `documentId`) - not versions
- Size should limit the number of documents returned per page - not versions

Or is it possible to filter results to only return one version per document? Something like a SQL-Subselect.

argh... i am really stuck here. Don't want to switch back to solr again 😒

---

<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:34pm UTC](https://discuss.elastic.co/t/group-and-filter-results/55775/8 "2017-07-05T22:34:27Z")

</div>


