Search code examples
elasticsearchopensearch

ElasticSearch null_pointer_exception when trying to access any object type of field using ctx._source


I have a index mapping like below

PUT /customer-index
{
  "mappings":{
    "properties":{
        "customers.id": {
        "type": "long"
      },
      "customers.name": {
        "type": "text",
        "norms": false
      },
      "customers.company": {
        "type": "text",
        "norms": false
      }
    }
  }
}

To this index, I have added two documents

PUT /customer-index/_doc/1
{
  "customers.company" : "google",
  "customers.id" : 1,
  "customers.name" : "adams"
}

PUT /customer-index/_doc/2
{
  "customers.company" : "apple",
  "customers.id" : 2,
  "customers.name" : "james"
}

Now I am trying to use update by query to update company to samsung where id is 2 . In real scenario, I have to update multiple docs in multiple indexes where id matches, that is why I am using update by query. But for simplicity, I have posted like this

POST /customer-index/_update_by_query
{
  "script": {
    "source": "ctx._source.customers.company = params.company",
    "lang": "painless",
    "params": {
      "company": "samsung"
    }
  },
  "query": {
    "term": {
      "customers.id": 2
    }
  }
}

But it is always throwing null_pointer_exception

{
  "error": {
    "root_cause": [
      {
        "type": "script_exception",
        "reason": "runtime error",
        "script_stack": [
          "ctx._source.customers.company = params.company",
          "                     ^---- HERE"
        ],
        "script": "ctx._source.customers.company = params.company",
        "lang": "painless",
        "position": {
          "offset": 21,
          "start": 0,
          "end": 46
        }
      }
    ],
    "type": "script_exception",
    "reason": "runtime error",
    "script_stack": [
      "ctx._source.customers.company = params.company",
      "                     ^---- HERE"
    ],
    "script": "ctx._source.customers.company = params.company",
    "lang": "painless",
    "position": {
      "offset": 21,
      "start": 0,
      "end": 46
    },
    "caused_by": {
      "type": "null_pointer_exception",
      "reason": "Cannot invoke \"Object.getClass()\" because \"callArgs[0]\" is null"
    }
  },
  "status": 400
}

Adding a null check can avoid this error but my question is why I am getting null_pointer_exception when I have the document present in the index. I have checked at lot of places but still no luck. Please help.


Solution

  • Since customers is not an object type, you need to access it like this:

    ctx._source['customers.company']
    

    Your query would work if you have declared your customers field like this:

    PUT /customer-index
    {
      "mappings":{
        "properties":{
          "customers": {
            "type": "object",
            "properties": {
              "id": {
                "type": "long"
              },
              "customers.name": {
                "type": "text",
                "norms": false
              },
              "customers.company": {
                "type": "text",
                "norms": false
              }
            }
          }
        }
      }
    }