1

I am trying to create a custom scripted Aggregation in Elasticsearch using the default scripting language Groovy.

My data set in elasticsearch is:

"days_open": [
{
"open": "0800",
"close": "2200",
"dotw": "monday"
}
,
{
"open": "0800",
"close": "2300",
"dotw": "tuesday"
}
,
{
"open": "0800",
"close": "2200",
"dotw": "wednesday"
}
,
{
"open": "0800",
"close": "2300",
"dotw": "thursday"
}
,
{
"open": "0800",
"close": "2300",
"dotw": "friday"
}
,
{
"open": "0800",
"close": "1700",
"dotw": "saturday"
}
]

I want to make an aggregation "Open Now" that will display all the busnesses with this nested data as "open".

"open_now": {
  "filter": {
    "script": {
      "script": {
        "inline": "days_open = _source.days_open; days_open.each {day-> if (day.dotw == 'wednesday' && day.open < 1200 && day.close > 1200) { return true; }}; return false;"
      }
    }
  }
}

However I'm receiving an error like this:

"reason": {
    "type": "script_exception",
    "reason": "failed to run inline script [days_open = _source.days_open; days_open.each {day-> if (day.dotw == 'wednesday' && day.open < 1200 && day.close > 1200) { return true; }}; return false;] using lang [groovy]",
    "caused_by": {
        "type": "no_class_def_found_error",
        "reason": "sun/reflect/MethodAccessorImpl",
            "caused_by": {
                 "type": "class_not_found_exception",
                 "reason": "sun.reflect.MethodAccessorImpl"
             }
         }
      }

It seems that the days_open variable value is this: [{dotw=monday, close=2200, open=0800}, {dotw=tuesday, close=2300, open=0800}, {dotw=wednesday, close=2200, open=0800}, {dotw=thursday, close=2300, open=0800}, {dotw=friday, close=2300, open=0800}, {dotw=saturday, close=1700, open=0800}], which I can get from the _head plugin in Elasticsearch using native queries, but I don't know how to get debug information further than that from Groovy in the interface.

I am using the https://github.com/ongr-io/ElasticsearchDSL ONGR Elasticsearch bundle which appears to have a bug currently in Nested Aggs (it surrounds things twice duplicate keys), but putting raw nested aggs don't really give me the results I'm looking for anyways. I'm looking for single results that look like this:

"open_now": {
   "doc_count": 5
},

Which would translate "5 business are currently open (out of 20)", no buckets. Scripting seemed like the best option here, guide me if I'm wrong or if I'm missing something!

Basically I need a script or an agg in ElasticsearchDSL that can give me the result I am looking for. I currently have other aggs that work just fine on single fields like "has_website" if the field "business.website" is true, but since this one requires a little logic to determine "open now", I'm not sure how to go about it in a way that works.

1 Answer 1

1

It's funny how you always find a solution after 4 hours and seeking help.

I managed to make the query work correctly by using Java style for statements: The Groovy Query:

days_open = _source.days_open; 
for (day in days_open) { 
    if (day.dotw == 'wednesday' && day.open < '1200' && day.close > '1200') {
       return true; 
    }
}; 
return false;

The ElasticsearchDSL Code:

    //OPEN NOW 
    $now = new \DateTime("NOW");
    $day = strtolower($now->format('l'));
    $time = $now->format('Hi');

    $openNowAgg = new \ONGR\ElasticsearchDSL\Aggregation\FilterAggregation('open_now'); 
    $openScript = new \ONGR\ElasticsearchDSL\Query\ScriptQuery("days_open = _source.days_open; for (day in days_open) { if (day.dotw == '{$day}' && day.open < '{$time}' && day.close > '{$time}') { return true; }}; return false;");
    $openNowAgg->setFilter($openScript); 
    $search->addAggregation($openNowAgg);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.