Search code examples
javascriptelasticsearchelasticsearch-6

Elasticsearch JS - Variable [x] is not defined


In a test Elasticsearch index, I have indexed a document, and I now want to update the document by setting its length property to 100. I want to do this through scripting (as this is a simplified example to illustrate my problem) via the elasticsearch package.

client.update({
  index: 'test',
  type: 'object',
  id: '1',
  body: {
    script: 'ctx._source.length = length',
    params: { length: 100 }
  }
})

However, I receive the following error:

{
  "error": {
    "root_cause": [
      {
        "type": "remote_transport_exception",
        "reason": "[6pAE96Q][127.0.0.1:9300][indices:data/write/update[s]]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "failed to execute script",
    "caused_by": {
      "type": "script_exception",
      "reason": "compile error",
      "script_stack": [
        "ctx._source.length = length",
        "                     ^---- HERE"
      ],
      "script": "ctx._source.length = length",
      "lang": "painless",
      "caused_by": {
        "type": "illegal_argument_exception",
        "reason": "Variable [length]is not defined."
      }
    }
  },
  "status": 400
}

This happens even though I have included the length property in body.params.length.

Using the following:

  • Elasticsearch server v6.1.1
  • Elasticsearch JavaScript client v14.1.0

How can I resolve this issue?


Solution

  • The documentation is wrong at https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#api-update

    In their example, they put:

    client.update({
      index: 'myindex',
      type: 'mytype',
      id: '1',
      body: {
        script: 'ctx._source.tags += tag',
        params: { tag: 'some new tag' }
      }
    }, function (error, response) {
      // ...
    });
    

    Whilst in fact, body.script should read:

    client.update({
      index: 'myindex',
      type: 'mytype',
      id: '1',
      body: {
        script: {
          lang: 'painless',
          source: 'ctx._source.tags += params.tag',
          params: { tag: 'some new tag' }
        }
      }
    }, function (error, response) {
      // ...
    });
    
    
    

    Therefore, if you change your script to:

    script: {
      lang: 'painless',
      source: 'ctx._source.length = params.length',
      params: { length: 100 }
    }
    

    it should work!


    You may want to reference the Painless Examples - Updating Fields with Painless page!