4

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"
  }
Or Weinberger
  • 7,332
  • 23
  • 71
  • 116
  • Have you tried `size()` instead of `length`? – Val Jun 14 '17 at 05:17
  • Yes, getting the same error message. If I update a single document everything works (with `.length`), but when I try to run an `update_by_query` I get this error message. I suspect it is because some documents do not have the `likes` object, but I have the `if` statement to handle that. – Or Weinberger Jun 14 '17 at 15:02
  • I think your condition `ctx._source.likes != ''` should read `ctx._source.likes != null` – Val Jun 14 '17 at 22:56
  • Have you tried using something like `ctx._source['likes.data.name'].values.length`? – skipper Jun 21 '17 at 11:11

2 Answers2

5

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.

1

Try this

ctx._source['likes']['data'].size()