5

I have the following query which currently uses dynamic scripting. I have since found that my host doesn't support this, as it has wider reaching security implications. How would I rewrite this script so that it doesn't use dynamic script?

{
  "size": 0,
  "aggs": {
    "filtered_cells": {
      "filter": {
        "geo_bounding_box": {
          "loc": {
            "top_left": "58.645976, -13.515625",
            "bottom_right": "50.524473, 2.436523"
          }
        }
      },
      "aggs": {
        "cells": {
          "geohash_grid": {
            "field": "loc",
            "precision": 2
          },
          "aggs": {
            "center_lat": {
              "avg": {
                "script": "doc['loc'].lat"
              }
            },
            "center_lon": {
              "avg": {
                "script": "doc['loc'].lon"
              }
            }
          }
        }
      }
    }
  },
  "query": {
    "match_all": {}
  }
}
Mick Walker
  • 3,862
  • 6
  • 47
  • 72
  • Can you [move the script to file](https://www.elastic.co/blog/running-groovy-scripts-without-dynamic-scripting)? Or, better said, does your host allow you to place .groovy files inside the ES installation directory? – Andrei Stefan May 28 '15 at 11:45

2 Answers2

2

You can store your scripts on the file system and reference them from within your query/aggregations.

Create a file named config/scripts/lat.groovy with the following content

 doc['loc'].lat

Create another file named config/scripts/lon.groovy with the following content

 doc['loc'].lon

Then change your query to this:

{
  "size": 0,
  "aggs": {
    "filtered_cells": {
      "filter": {
        "geo_bounding_box": {
          "loc": {
            "top_left": "58.645976, -13.515625",
            "bottom_right": "50.524473, 2.436523"
          }
        }
      },
      "aggs": {
        "cells": {
          "geohash_grid": {
            "field": "loc",
            "precision": 2
          },
          "aggs": {
            "center_lat": {
              "avg": {
                "script_file": "lat"
              }
            },
            "center_lon": {
              "avg": {
                "script_file": "lon"
              }
            }
          }
        }
      }
    }
  },
  "query": {
    "match_all": {}
  }
}
Val
  • 207,596
  • 13
  • 358
  • 360
1

Apart from placing the actual script on a .groovy file, like I mentioned (more details here), you could define a native script. More involved than the groovy-on-file approach but is much more flexible. In your case, the script is really simple :-) and you don't need the flexibility though, but the option exists (implementation sample from yours truly): ElasticSearch: aggregation on _score field w/ Groovy disabled

Community
  • 1
  • 1
Andrei Stefan
  • 51,654
  • 6
  • 98
  • 89