Scripted field to count array length

Or Weinberger picture Or Weinberger · Jun 13, 2017 · Viewed 7.4k times · Source

I have the following document:

{
  "likes": {
    "data": [
      {
        "name": "a"
      },
      {
        "name": "b"
      },
      {
        "name": "c"
      }
    ]
  }
}

I'm trying to run an update_by_query that will add a field called 'like_count' with the number of array items inside likes.data

It's important to know that not all of my documents have the likes.data object.

I've tried this:

POST /facebook/post/_update_by_query
{
  "script": {
  "inline": "if (ctx._source.likes != '') { ctx._source.like_count = ctx._source.likes.data.length }",
    "lang": "painless"
  }
}

But getting this error message:

{
    "type": "script_exception",
    "reason": "runtime error",
    "script_stack": [
      "ctx._source.like_count = ctx._source.likes.data.length }",
      "                                               ^---- HERE"
    ],
    "script": "if (ctx._source.likes != '') { ctx._source.like_count = ctx._source.likes.data.length }",
    "lang": "painless"
  }

Answer

kennywu0616 picture kennywu0616 · Jun 22, 2017

Try ctx._source['likes.data.name'].length

According to https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html, the object array in ES is flattened to

{
   "likes.data.name" :["a", "b", "c"] 
}

The object array datatype we thought is Nest datatype.