3

I am trying to average a field in elastic search,

"aggs": {
      "avg_timedifference": {
         "avg": {
            "script" : "doc['@timestamp'].value"
         }
      }

this works,

where the mapping is,

    {
            "_index" : "justchill",
            "_type" : "doc",
            "_id" : "cRP1bWEB6Z3gZHtPaXv1",
            "_score" : 1.0,
            "_source" : {

              "port" : 80,
              "bing.sss-ccc.tc.DOWNSTREAM_dropped.bong" : 33.0,
              "@timestamp" : "2018-02-07T01:50:55.000Z",
              "message" : "ccc.dna-ccc.tc.DOWNSTREAM_dropped.kkk 33 1517968255",
              "@version" : "1",
              "host" : "localhost"
            }
          },
          {
            "_index" : "justchill",
            "_type" : "doc",
            "_id" : "cRP1bWEB6Z3gZHtPaXv1",
            "_score" : 1.0,
            "_source" : {

              "port" : 80,
              "bong.sss-ccc.tc.DOWNSTREAM_dropped.bing" : 33.0,
              "@timestamp" : "2018-02-07T01:50:55.000Z",
              "message" : "ccc.dna-ccc.tc.DOWNSTREAM_dropped.kkk 33 1517968255",
              "@version" : "1",
              "host" : "localhost"
            }
          },

what i want to do is access the fields here temporarly named bing..bong and bong ..bing .The field is dynamically mapped , any way to access the same?

JVM
  • 41
  • 2

1 Answers1

0

You can access all of the source as a java-Map via params._source (sic).

This in turn will give you the possibility to look for keys which are present via the keySet()-method, and you can find out the exact names of your fields.

In your example you will get something like the following script:

for (field in params._source.keySet()) {
  if (field.startsWith('bong')) {
    return doc[field+'.keyword']
  }
}
return 'No field found matching bong'

This is just a basic setup; whether you need to specify you want the keyword is up to you, and this solution will only take the first match.

Note that if you want to look into multi-layered fields, you can't just use the dot to look into params._source. If you want to, say, return all fields under host under a subfield connection with a subfield something starting with ip, you'd want for (field in params._source['host']['connection'].keySet())

And unfortunately, whether this approach works also depends on the context. As far as I've tested it works in an aggregation and in scripted fields, but not in a scripted query.

Finally, note that the "parameter" _source is a kind of automatic parameter, there is no need to specify anything under your params

And for the record: I know I'm late, but I stumbled across this problem myzelf, and the answer may be useful for others still looking.

Emil Bode
  • 1,784
  • 8
  • 16