2016-04-13 2 views
2

Я хочу добавить объект в поле nested каждое время обновления.elasticsearch: использовать скрипт для обновления вложенного поля?

К примеру, у меня есть документ:

{ 
    "test":[{"remark":"remark1"}] 
} 

В следующий раз, я хочу, чтобы добавить remark объект в тестовом поле и сохранить старый remark objects.And результат:

{ 
    "test":[{"remark":"remark1"},{"remark":"remark2"}] 
} 
?

Как достичь этого

Редактировать Я использую скрипт:

{ 
    "script": "ctx._source.test= ((ctx._source.test?: []) += remarkItem)", 
    "params": { 
     "remarkItem": { 
      "remark": "addd" 
     } 
    } 
} 

Но я получаю исключение:

{ 
"error": { 
    "root_cause": [ 
     { 
      "type": "remote_transport_exception", 
      "reason": "[es77][10.14.84.77:9300][indices:data/write/update[s]]" 
     } 
    ], 
    "type": "illegal_argument_exception", 
    "reason": "failed to execute script", 
    "caused_by": { 
     "type": "script_exception", 
     "reason": "Failed to compile inline script [ctx._source.test= ((ctx._source.test?: []) += remarkItem)] using lang [groovy]", 
     "caused_by": { 
      "type": "script_exception", 
      "reason": "failed to compile groovy script", 
      "caused_by": { 
       "type": "multiple_compilation_errors_exception", 
       "reason": "startup failed:\na8220b2cf14b8b7ebeead7f068416882d04fa25d: 1: \nclass org.codehaus.groovy.ast.expr.ElvisOperatorExpression, with its value '(ctx._source.test) ? ctx._source.test: []', is a bad expression as the left hand side of an assignment operator at line: 1 column: 82. File: a8220b2cf14b8b7ebeead7f068416882d04fa25d @ line 1, column 82.\n CILastCallResultRemark ?: []) += remarkI\n         ^\n\n1 error\n" 
      } 
     } 
    } 
}, 
"status": 400 
} 

редактировать

Теперь я хочу, чтобы добавить поле, чтобы обеспечить обновление или вставить объект. Например:

{ 
    "test":[{"remark":"remark1","id":"1"}] 
} 

Когда я обновить поле, когда идентификатор существует, я буду обновлять object.On противный, я вставлю объект.

+0

Смотрите этот ответ: http://stackoverflow.com/questions/34512491/elasticsearch-groovy-script-syntax-for-generation-of-nested-fields/34512738 # 34512738 – Val

+0

@Val { "script": "ctx._source.test = ((ctx._source.test? : []) + = remarkItem) ", "params": { "remarkItem": { "примечание": "addd" } } } .. У этого сценария есть ошибка. Почему? –

+0

Обновите свой вопрос тем, что вы пробовали, и ошибкой, которую вы получили. – Val

ответ

5

Предлагаю попробовать сценарий, подобный этому, который принимает два параметра в аргументе. Он будет проверять, если какой-либо из вложенных объектов уже содержит данный идентификатор:

  • если да, то будет обновлять данный remark
  • если нет, то он будет вставить новый вложенный объект в test массиве.

Сценарий выглядит следующим образом:

def updated = false 
ctx._source.test?.each { obj -> 
    if (obj.id == item.id) { 
     obj.remark = item.remark 
     updated = true 
    } 
} 
if (!updated) { 
    ctx._source.test = ((ctx._source.test ?: []) + item) 
} 

После встраиваемых и с надлежащей точкой с запятой, сценарий выглядит следующим образом:

{ 
    "script": "def updated = false; ctx._source.test?.each { obj -> if (obj.id == item.id) { obj.remark = item.remark; updated = true } }; if (!updated) { ctx._source.test = ((ctx._source.test ?: []) + item)}", 
    "params": { 
     "item": { 
      "remark": "addd", 
      "id": "1" 
     } 
    } 
} 
+0

Спасибо, скрипт работает нормально! –

+0

{ { "params": { "item": "ctx._source.CILastCallResultRemark? .each {obj -> if (obj.id == item.id) {obj = null}}", " { "id": "2" } } }, Почему этот сценарий не может удалить объект? –

+0

'obj = null' не удаляет объект, а просто устанавливает его в null. Чтобы удалить объекты, вам нужно выполнить другой скрипт. – Val

Смежные вопросы