elhefe
elhefe

Reputation: 3494

Select document field with parameter in elasticsearch update by query API

ElasticSearch version = 5.5

I've inherited some code that updates arbitrary document fields via the update by query API to an arbitrary value like this:

{
 "query": ...
 "script": {
   "inline": "ctx._source." + field + " = " + value + ";"
   }
 }

This occasionally causes the query to fail due to the maximum compilations per minute circuit breaker.

A partial update would work well for this case, but as far as I can determine, partial updates are only supported in the standard update API, not the update by query API:

{
 "query": ...
 "doc": {
   field: value
   }
 }

Unknown key for a START_OBJECT in [doc]

At least, being an ES newb, I assume that's what that error means. There's also no mention of doc in the update by query API docs.

Assuming I'm right that partial updates won't work, parameterizing the script as recommended in the scripting guide seems like the next step, but there doesn't appear to be any way to access a source field specified by a parameter:

# I wouldn't expect this to work, but tried anyway
{
 "query": ...
 "script": {
   "inline": "ctx._source.params.field = value;",
   "params": {
      "field": field,
      "value": value
      }
   }
 }

"caused_by":{"type":"null_pointer_exception","reason":null}}

Trying to access the field via doc-values also doesn't seem to work:

{
 "query": ...
 "script": {
   "inline": "doc[params.field] = value;",
   "params": {
      "field": field,
      "value": value
      }
   }
 }

caused_by":{"type":"null_pointer_exception","reason":null}}

Is there any way to fix this script or is a more extensive refactor required?

Upvotes: 2

Views: 3595

Answers (1)

Val
Val

Reputation: 217314

You're right, partial updates are not supported by the update-by-query API (+ here).

You've almost found the right way to do it, though, which is like this:

{
 "query": ...
 "script": {
   "inline": "ctx._source[params.field] = params.value;",
   "params": {
      "field": field,
      "value": value
      }
   }
 }

UPDATE: As of ES 6, replace inline by source

Upvotes: 10

Related Questions