Get previous and next document by date in Elasticsearch

My Elasticsearch index contains documents, each with a date field. Documents can be sorted by date.

Suppose I have a specific document id and its date, what is the best way to get the previous and next document inside the index by date?

I looked at a fuzzy query with dates, but it doesn't directly solve the problem. It will return the most similar documents, but not necessarily the previous and next.

+3


source to share


1 answer


Here's one way to do it, but it accepts two requests. For verification, I defined a simple index and added some docs:

PUT /test_index
{
   "settings": {
      "number_of_shards": 1
   },
   "mappings": {
      "doc": {
         "properties": {
            "doc_date": {
               "type": "date",
               "format": "YYYY-MM-dd"
            }
         }
      }
   }
}

POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"doc_date":"2015-5-21"}
{"index":{"_id":3}}
{"doc_date":"2015-5-22"}
{"index":{"_id":2}}
{"doc_date":"2015-5-23"}
{"index":{"_id":4}}
{"doc_date":"2015-5-24"}
{"index":{"_id":6}}
{"doc_date":"2015-5-25"}
{"index":{"_id":5}}
{"doc_date":"2015-5-26"}

      

Now I can select a date, say "2015-5-23"

, and get the following document like this:

POST /test_index/_search
{
   "size": 1,
   "query": {
      "constant_score": {
         "filter": {
            "range": {
               "doc_date": {
                  "gt": "2015-5-23"
               }
            }
         }
      }
   },
   "sort": [
      {
         "doc_date": {
            "order": "asc"
         }
      }
   ]
}
...
{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 3,
      "max_score": null,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "4",
            "_score": null,
            "_source": {
               "doc_date": "2015-5-24"
            },
            "sort": [
               1432425600000
            ]
         }
      ]
   }
}

      

and the previous one:



POST /test_index/_search
{
   "size": 1,
   "query": {
      "constant_score": {
         "filter": {
            "range": {
               "doc_date": {
                  "lt": "2015-5-23"
               }
            }
         }
      }
   },
   "sort": [
      {
         "doc_date": {
            "order": "desc"
         }
      }
   ]
}
...
{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": null,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "3",
            "_score": null,
            "_source": {
               "doc_date": "2015-5-22"
            },
            "sort": [
               1432252800000
            ]
         }
      ]
   }
}

      

Not sure how to do this in one request. I'll think about it.

Here's the code I used for testing:

http://sense.qbox.io/gist/ffeda4baeafac27dcc11e2010594015c98e6d40f

+1


source







All Articles