# Sort by next date in range from array of dates

**URL:** <https://discuss.elastic.co/t/sort-by-next-date-in-range-from-array-of-dates/48188>\
**Category:** Elasticsearch\
**Created:** [April 22, 2016, 4:08pm UTC](https://discuss.elastic.co/t/sort-by-next-date-in-range-from-array-of-dates/48188 "2016-04-22T16:08:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Geoff\_Stockham](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@Geoff\_Stockham](https://discuss.elastic.co/u/Geoff_Stockham)\
**Post date:** [April 22, 2016, 4:08pm UTC](https://discuss.elastic.co/t/sort-by-next-date-in-range-from-array-of-dates/48188/1 "2016-04-22T16:08:31Z")

</div>

Hi,

I'm wondering if the following is possible? I've tried to simplify my issue into a short example:

Given three items, each with an array of dates:

`{ "title": "item 1", "dates": ["2016-04-21T12:00:00.000Z", "2016-04-29T12:00:00.000Z", "2016-05-05T12:00:00.000Z"] } { "title": "item 2", "dates": ["2016-04-23T12:00:00.000Z", "2016-04-30T12:00:00.000Z", "2016-05-07T12:00:00.000Z"] } { "title": "item 3", "dates": ["2016-04-27T12:00:00.000Z", "2016-04-28T12:00:00.000Z", "2016-05-29T12:00:00.000Z"] }`

I can search for a range of dates:  
`"query": { "bool": { "must": [{ "range": { "dates": { "from": "2016-04-25T00:00:00.000Z", "to": "2016-04-30T00:00:00.000Z" } } }] } }`

Which correctly returns Item 1 and Item 3. However, within my date range, the **next occurring date** is actually in Item 3. (Date range is 25/04 to 30/04, Item 3 is on 28/04, Item 1 is on 29/04).

However, adding a sort

`"sort": [ { "dates": { "order": "asc" } }`

returns Item 1 first, presumably because the first date in that array is earlier.

Is there any way of doing this (without scripting)? Or is there another way of structuring my data that may allow it?

Thanks for any pointers!

Geoff

---

<div class="post-metadata">

**Author:** ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)\
**Post date:** [April 22, 2016, 4:22pm UTC](https://discuss.elastic.co/t/sort-by-next-date-in-range-from-array-of-dates/48188/2 "2016-04-22T16:22:19Z")

</div>

Havent tried it out, but you could probably structure your data so that you have "items" as parent objects and "dates" as child objects, then do the range query inside a "has\_child" query. Don't know how sorting behaves then, to be honest, but I think the problem why this currently doesn't work is because putting all those dates together in one document.

---

<div class="post-metadata">

**Author:** ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)\
**Post date:** [April 22, 2016, 8:01pm UTC](https://discuss.elastic.co/t/sort-by-next-date-in-range-from-array-of-dates/48188/3 "2016-04-22T20:01:56Z")

</div>

Hi Geoff,

I had a quick go at my initial idea, came up with something. Its a bit more complicated as I thought, so maybe there's better ways to do it, but at least for the toy example it seems to work.

I've written down the steps in this little [gist](https://gist.github.com/cbuescher/ad339f0b7879a3d5bdd8eff48f1d41be).

First, if you model your data with a parent-child relation you can separate the items and the dates. When we then do the "range" query inside a "has\_child" query we still get get item1 and item3, but now only the child documents where the date is in the range match.

Now, the sorting gets difficult because according to [this issue](https://github.com/elastic/elasticsearch/issues/2917) sorting by parent/child is not possible yet. But there is a [workaround](http://stackoverflow.com/questions/14504180/elasticsearch-sorting-by-nested-documents-values/14519947#14519947) using function\_score\_query. Basically we use the date (the internal long value) of the matching child doc as score and then sort by score on the top level.

I'm not sure if this works well in scale and if you can structure your data like this, but it was a fun thing to try. Let me know if this helps.

---

<div class="post-metadata">

**Author:** ![Geoff\_Stockham](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@Geoff\_Stockham](https://discuss.elastic.co/u/Geoff_Stockham)\
**Post date:** [April 25, 2016, 8:12am UTC](https://discuss.elastic.co/t/sort-by-next-date-in-range-from-array-of-dates/48188/4 "2016-04-25T08:12:52Z")

</div>

Thanks very much. My data is actually in more of a parent-child relationship anyway (I had simplified it for this example), so I will try this out and report back!

---

<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:56pm UTC](https://discuss.elastic.co/t/sort-by-next-date-in-range-from-array-of-dates/48188/5 "2017-07-05T22:56:33Z")

</div>


