我正在尝试使用默认脚本语言Groovy在Elasticsearch中创建自定义脚本聚合。
我在elasticsearch中设置的数据是:
"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"
}
]
我想进行一个聚合“立即打开”,将所有带有此嵌套数据的业务显示为“打开”。
"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;"
}
}
}
}
但是我收到这样的错误:
"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"
}
}
}
看来
days_open
变量值是这样的:[{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}]
,我可以使用本地查询从Elasticsearch的_head插件中获取,但我不知道如何从界面中的Groovy那里获取调试信息。我正在使用https://github.com/ongr-io/ElasticsearchDSL ONGR Elasticsearch bundle 包,该 bundle 包似乎在嵌套的Aggs中存在一个错误(它把东西包围两次,重复键),但是无论如何放置原始嵌套的aggs并不能真正为我提供我想要的结果。我正在寻找看起来像这样的单个结果:
"open_now": {
"doc_count": 5
},
这将翻译为“目前有5家企业((在20家中)未营业)”,没有存储桶。脚本似乎是这里的最佳选择,如果我输入错误或缺少某些内容,请引导我!
基本上,我需要ElasticsearchDSL中的脚本或agg可以给我想要的结果。我目前还有其他aggs,如果“business.website”字段为true,则可以在诸如“has_website”之类的单个字段上正常工作,但是由于此操作需要一点逻辑来确定“立即打开”,因此我不确定关于它的一种有效的方式。
最佳答案
有趣的是,您总是在4小时后找到解决方案并寻求帮助。
我设法通过使用Java样式for
语句使查询正常工作:
Groovy查询:
days_open = _source.days_open;
for (day in days_open) {
if (day.dotw == 'wednesday' && day.open < '1200' && day.close > '1200') {
return true;
}
};
return false;
ElasticsearchDSL代码:
//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);
关于elasticsearch - Elasticsearch和Groovy脚本嵌套字段聚合匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35463208/