我需要使用新字段更新特定类型的现有文档。此新字段应设置为文档中日期时间字段指定的日期的本地日期名称。日期时间字段的格式为yyyy-MM-dd< T' HH:mm:ss,是UTC格式,但没有明确的时区代码。
我想用Groovy做这件事,但没有Java经验。我猜我需要:
1)将日期时间设置为UTC区域设置
2)在这种情况下转换为本地区域设置(设置为Europe / London)
3)从转换日期获取日期名称并使用它设置新字段(日期名称)
如果我使用以下update_by_query:
POST /myindex/_update_by_query
{
"script": {
"inline": "ctx._source.dayname = Some_function(ctx._source.datetime)"
},
"query": {
"term": {
"_type": "myDocType"
}
}
}
使用一些Groovy函数(替换上面的Some_function)是否有一种简单的方法可以做到这一点。
任何提示都会非常感激!
更新 - 感谢tim_yates我有以下Sense控制台代码:
POST /rating/_update_by_query
{
"script": {
"inline": "ctx._source.day = Date.parse(\"yyyy-MM-dd'T'HH:mm:ss\", ctx._source.datetime, java.util.TimeZone.getTimeZone('UTC')).format('EEEE', java.util.TimeZone.getTimeZone('Europe/London'))"
},
"query": {
"term": {
"_type": "transaction"
}
}
}
不幸的是,这会生成以下错误消息:
{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "failed to run inline script [ctx._source.day = Date.parse(\"yyyy-MM-dd'T'HH:mm:ss\", ctx._source.datetime, java.util.TimeZone.getTimeZone('UTC')).format('EEEE', java.util.TimeZone.getTimeZone('Europe/London'))] using lang [groovy]"
}
],
"type": "script_exception",
"reason": "failed to run inline script [ctx._source.day = Date.parse(\"yyyy-MM-dd'T'HH:mm:ss\", ctx._source.datetime, java.util.TimeZone.getTimeZone('UTC')).format('EEEE', java.util.TimeZone.getTimeZone('Europe/London'))] using lang [groovy]",
"caused_by": {
"type": "missing_property_exception",
"reason": "No such property: java for class: 1209ff7fb16beac3a71ff2a276ac2225f7c4505b"
}
},
"status": 500
}
虽然如果我删除对getTimeZone的引用 - 确切的Sense控制台代码,它确实有效,如下所示:
POST /rating/_update_by_query
{
"script": {
"inline": "ctx._source.day = Date.parse(\"yyyy-MM-dd'T'HH:mm:ss\", ctx._source.datetime).format('EEEE')"
},
"query": {
"term": {
"_type": "transaction"
}
}
}
我不确定为什么getTimeZone方法失败了。我已经尝试过" TimeZone.getTimeZone"而不是" java.util.TimeZone.getTimeZone"
答案 0 :(得分:0)
您需要的Groovy代码(对于Java 7)将非常类似于此:
Date.parse("yyyy-MM-dd'T'HH:mm:ss", ctx._source.datetime, TimeZone.getTimeZone('UTC'))
.format('EEEE', TimeZone.getTimeZone("Europe/London"))
答案 1 :(得分:0)
好的,更多的研究让我明白tim_yates的答案是正确的,我们只需要将所需的Java类列入白名单。我们通过以下方式做到了这一点:
nano $ JAVA_HOME / lib / security / java.policy
并添加:
permission org.elasticsearch.script.ClassPermission“java.util.TimeZone”;
...然后重启ES服务。
请注意,这会将所有用户的类列入白名单,而不仅仅是ES用户。参见:
https://www.elastic.co/guide/en/elasticsearch/reference/2.2/modules-scripting-security.html