# Updating dates in Painless

**URL:** <https://discuss.elastic.co/t/updating-dates-in-painless/213784>\
**Category:** Elasticsearch\
**Created:** [January 4, 2020, 8:36pm UTC](https://discuss.elastic.co/t/updating-dates-in-painless/213784 "2020-01-04T20:36:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ffknob](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ffknob/32/37008_2.png) [@ffknob](https://discuss.elastic.co/u/ffknob)\
**Post date:** [January 4, 2020, 8:36pm UTC](https://discuss.elastic.co/t/updating-dates-in-painless/213784/1 "2020-01-04T20:36:03Z")

</div>

Hi there

today I was a little bit confused with the documentation about the Painless language. My goal was to use the `_update_by_query` API to correct the year of some date fields. I was happy to read that...

```auto
Date fields are exposed as ZonedDateTime, so they support methods like getYear, getDayOfWeek

```

[https://www.elastic.co/guide/en/elasticsearch/painless/7.5/painless-walkthrough.html#modules-scripting-painless-dates](https://www.elastic.co/guide/en/elasticsearch/painless/7.5/painless-walkthrough.html#modules-scripting-painless-dates)

SO I was hoping that the below code would work...

```auto
POST my-index/_update_by_query
{
  "script": {
    "source": """
ctx._source.myDate = ctx._source.myDate.withYear(year);
    """,
    "lang": "painless"
  }
}

```

...but it failed with:

```auto
dynamic method [java.lang.String, withYear/1] not found

```

I managed to get my update to work by first parsing the field, as shown below:

```auto
POST my-index/_update_by_query
{
  "script": {
    "source": """
ctx._source.myDate = ZonedDateTime.parse(ctx._source.myDate).withYear(year);
    """,
    "lang": "painless"
  }
}

```

Was that expected to work this way? Did I misunderstood something?

---

<div class="post-metadata">

**Author:** ![oranieri](https://avatars.discourse-cdn.com/v4/letter/o/919ad9/32.png) [@oranieri](https://discuss.elastic.co/u/oranieri)\
**Post date:** [January 5, 2020, 1:36am UTC](https://discuss.elastic.co/t/updating-dates-in-painless/213784/2 "2020-01-05T01:36:57Z")

</div>

Hi Flavio,

It depends of the [painless context](https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-contexts.html) where the script is being executed.

For example, when getting values from source in **\_update\_by\_query** context (using **ctx.\_source** or **ctx['\_source']**), you will receive the value(s) from [JSON schema](https://www.w3schools.com/js/js_json_datatypes.asp), which doesn't contain a type date.

Let's create a index with dynamic mapping (types will be date, long, boolean respectively, you may get the index mapping to double check):

```auto
PUT myindex/_doc/1
{
  "date": "2020-01-01",
  "number": 123,
  "boolean": true
}

```

On [\_update\_by\_query context](https://www.elastic.co/guide/en/elasticsearch/painless/7.5/painless-update-by-query-context.html), it will read the source into a Map with JSON structure:

```auto
ctx['_source'] (Map)
      Contains extracted JSON in a Map and List structure for the fields existing in a stored document.

```

A simple script for checking the types of each field and storing into a `debug` field.

```
POST myindex/_update_by_query
{
  "script": {
    "source": """
      ctx._source.debug = "";
      if(ctx._source.date instanceof String)
        ctx._source.debug += '{date} field is java.lang.String. ';
      if(ctx._source.number instanceof Integer)
        ctx._source.debug += '{number} field is java.lang.Integer. ';
      if(ctx._source.boolean instanceof Boolean)
        ctx._source.debug += '{boolean} field is java.lang.Boolean.';
    """,
    "lang": "painless"
  }
}

```

You will notice that the `date` field is parsed as `String` and not `Date`.

```auto
...
{
"date" : "2020-01-01",
"number" : 123,
"boolean" : true,
"debug" : "{date} field is java.lang.String.   
           {number} field is java.lang.Integer.   
           {boolean} field is java.lang.Boolean."
}
...

```

However using painless in the same index in a [field context](https://www.elastic.co/guide/en/elasticsearch/painless/7.5/painless-field-context.html) can be manipulated directly as a date:

```auto
GET myindex/_search
{
  "script_fields": {
    "my_year_plus_one": {
      "script": {
        "source": "doc['date'].value.year + 1"
      }
    }
  }
}

```

Result:

```auto
...
"fields" : {
  "my_year_plus_one" : [
    2021
  ]
 }
...

```

So in your case, it's indeed necessary to parse date from String to manipulate it.

Best Regards,  
Octavio Ranieri

---

<div class="post-metadata">

**Author:** ![ffknob](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ffknob/32/37008_2.png) [@ffknob](https://discuss.elastic.co/u/ffknob)\
**Post date:** [January 5, 2020, 9:37pm UTC](https://discuss.elastic.co/t/updating-dates-in-painless/213784/3 "2020-01-05T21:37:31Z")

</div>

What a great answer! Thank you @oranieri!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [February 2, 2020, 9:37pm UTC](https://discuss.elastic.co/t/updating-dates-in-painless/213784/4 "2020-02-02T21:37:34Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
