Elasticsearch - 在Groovy脚本

时间:2016-10-10 10:30:00

标签: datetime elasticsearch groovy inline

我需要使用新字段更新特定类型的现有文档。此新字段应设置为文档中日期时间字段指定的日期的本地日期名称。日期时间字段的格式为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"

2 个答案:

答案 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