#datetime #elasticsearch #groovy #inline
#дата и время #elasticsearch #groovy #встроенный
Вопрос:
Мне нужно обновить существующие документы определенного типа новым полем. Это новое поле должно быть установлено на название локального дня даты, заданной полем datetime в документе. Поле даты и времени имеет формат гггг-ММ-dd’T’HH: mm:ss, находится в UTC, но не имеет явного кода часового пояса.
Я бы хотел сделать это с помощью Groovy, но у меня нет опыта работы с Java. Я предполагаю, что мне нужно:
1) Установите для даты и времени значение UTC
2) Преобразовать в локальную локаль (в данном случае в Европу / Лондон)
3) Получите название дня из преобразованной даты и задайте с ним значение нового поля (dayname)
Если я использую следующий 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 — exact 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»
Комментарии:
1. какая версия Java работает под ним? 1.8?
2. Из того, что я вижу в документах, говорится, что Java 7 обновляет 55 или более позднюю версию
3. Да, так что это может быть Java 7 или 8… Для 8 есть более простой способ, чем для 7
4. JVM на узлах ES — 1.7.0_111, если это поможет? Я не знаю, но могу только предположить, что Goorvy будет использовать локальную JVM?
Ответ №1:
Код 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. Спасибо! Это работает, если я удаляю часовой пояс из .parse и .format . Но сбой, если я оставляю часовой пояс с ошибкой: нет такого свойства: Часовой пояс для класса: 123322031df312eb7093fea2da1f852e31e1a660
2. Странно … попробуйте
java.util.TimeZone.getTimeZone('UTC')
иjava.util.TimeZone.getTimeZone('Europe/London')
3. К сожалению, не повезло — я обновил свой вопрос выше. Спасибо за вашу помощь до сих пор!
Ответ №2:
Хорошо, немного больше исследований позволило мне понять, что ответ tim_yates был правильным, нам просто нужно было внести в белый список требуемый класс Java. Мы сделали это с помощью:
nano $JAVA_HOME/lib/security/java.policy
и добавление:
разрешение org.elasticsearch.script.ClassPermission «java.util.Часовой пояс»;
…затем перезапустите службы ES.
Обратите внимание, что этот класс выводится в белый список для всех пользователей, а не только для пользователя ES. См.:
https://www.elastic.co/guide/en/elasticsearch/reference/2.2/modules-scripting-security.html