简体   繁体   中英

Date_histogram Elasticsearch facet can't find field

I am using the date_histogram facet to find results based on a Epoch timestamp. The results are displayed on a histogram, with the date on the x-axis and count of events on the y-axis. Here is the code that I have that doesn't work:

angular.module('controllers', [])
  .controller('FacetsController', function($scope, $http) {
    var payload = {
      query: {
        match: {
          run_id: '9'
        }
      },
      facets: {
        date: {
          date_histogram: {
            field: 'event_timestamp',
            factor: '1000',
            interval: 'second'
          }
        }
      }
    }

It works if I am using field: '@timestamp' which is in ISO8601 format; however, I need it to now work with Epoch timestamps.

Here is an example of what's in my Elasticsearch, maybe this can lead to some answers:

{"@version":"1",
"@timestamp":"2014-07-04T13:13:35.372Z","type":"automatic",
"installer_version":"0.3.0",
"log_type":"access.log","user_id":"1",
"event_timestamp":"1404479613","run_id":"9"}
},

When I run this, I receive this error: POST 400 (Bad Request)

Any ideas as to what could be wrong here? I don't understand why I'd have such a difference from using the two different fields, as the only difference is the format. I researched as best I could and discovered I should be using 'factor', but that didn't seem to solve my problem. I am probably making a silly beginner mistake!

You need to set the indexing initially. Elasticsearch is good at defaults but it is not possible for it to determine if the provided value is a timestamp, integer or string. So its your job to tell Elasticsearch about the same.

Let me explain by example. Lets consider the following document is what you are trying to index:

{
   "@version": "1",
   "@timestamp": "2014-07-04T13:13:35.372Z",
   "type": "automatic",
   "installer_version": "0.3.0",
   "log_type": "access.log",
   "user_id": "1",
   "event_timestamp": "1404474613",
   "run_id": "9"
}

So initially you don't have an index and you index your document by making an HTTP request like so:

POST /test/date_experiments
{
   "@version": "1",
   "@timestamp": "2014-07-04T13:13:35.372Z",
   "type": "automatic",
   "installer_version": "0.3.0",
   "log_type": "access.log",
   "user_id": "1",
   "event_timestamp": "1404474613",
   "run_id": "9"
}

This creates a new index called test and a new doc type in index test called date_experiments .

You can check the mapping of this doc type date_experiments by doing so:

GET /test/date_experiments/_mapping

And what you get in the result is an auto-generated mapping that was generated by Elasticsearch:

{
   "test": {
      "date_experiments": {
         "properties": {
            "@timestamp": {
               "type": "date",
               "format": "dateOptionalTime"
            },
            "@version": {
               "type": "string"
            },
            "event_timestamp": {
               "type": "string"
            },
            "installer_version": {
               "type": "string"
            },
            "log_type": {
               "type": "string"
            },
            "run_id": {
               "type": "string"
            },
            "type": {
               "type": "string"
            },
            "user_id": {
               "type": "string"
            }
         }
      }
   }
}

Notice that the type of event_timestamp field is set to string . Which is why your date_histogram is not working. Also notice that the type of @timestamp field is already date because you pushed the date in the standard format which made easy for Elasticsearch to recognize your intention was to push a date in that field.

Drop this mapping by sending a DELETE request to /test/date_experiments and lets start from the beginning.

This time instead of pushing the document first, we will make the mapping according to our requirements so that our event_timestamp field is considered as a date.

Make the following HTTP request:

PUT /test/date_experiments/_mapping
{
   "date_experiments": {
      "properties": {
         "@timestamp": {
            "type": "date"
         },
         "@version": {
            "type": "string"
         },
         "event_timestamp": {
            "type": "date"
         },
         "installer_version": {
            "type": "string"
         },
         "log_type": {
            "type": "string"
         },
         "run_id": {
            "type": "string"
         },
         "type": {
            "type": "string"
         },
         "user_id": {
            "type": "string"
         }
      }
   }
}

Notice that I have changed the type of event_timestamp field to date . I have not specified a format because Elasticsearch is good at understanding a few standard formats like in the case of @timestamp field where you pushed a date. In this case, Elasticsearch will be able to understand that you are trying to push a UNIX timestamp and convert it internally to treat it as a date and allow all date operations on it. You can specify a date format in the mapping just in case the dates you are pushing are not in any standard formats.

Now you can start indexing your documents and starting running your date queries and facets the same way as you were doing earlier.

You should read more about mapping and date format .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM