# Groovy script to iterate through nested object for scoring throws error

**URL:** <https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904>\
**Category:** Elasticsearch\
**Created:** [October 25, 2016, 4:16pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904 "2016-10-25T16:16:56Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![pungent](https://avatars.discourse-cdn.com/v4/letter/p/a698b9/32.png) [@pungent](https://discuss.elastic.co/u/pungent)\
**Post date:** [October 25, 2016, 4:16pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/1 "2016-10-25T16:16:56Z")

</div>

I have a nested object `mygroup` in my document as follows:

```
{
  "name": "john",
  "mygroup": [
    {
      "start": 200,
      "end": 490
    },
    {
      "start": 800,
      "end": 900
    },
    {
      "start": 22,
      "end": 49
    }
  ]
}

```

One of my `script_score` in my `function_score` is as follows:

```
"script_score": {
  "params": {
    "gboost": -1350,
    "desired": 30,
    "delta": 10
  },
  "script": "doc['mygroup'].values.any{ if(it -> it.end >= desired && it.start <= desired) { return (it.end - delta) * 2} };" 
}

```

Here my goal is to find an object that matches my condition where `start` is \>= desired AND `end` \<= desired (There is always ONLY one object that will suffice this condition, that's guaranteed in my data storage), once I find that object then I would like to return `(it.end - delta) * 2` for score calculation

My above script `"doc['mygroup'].values.any{ if(it -> it.end >= desired && it.start <= desired) { return (it.end - delta) * 2} };"` is not working and it keeps throwing error. I am using ES 2.3 and groovy for scripting language.

---

<div class="post-metadata">

**Author:** ![nik9000](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nik9000/32/44947_2.png) [@nik9000](https://discuss.elastic.co/u/nik9000)\
**Post date:** [October 25, 2016, 5:12pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/2 "2016-10-25T17:12:10Z")

</div>

Can you post the error?

---

<div class="post-metadata">

**Author:** ![pungent](https://avatars.discourse-cdn.com/v4/letter/p/a698b9/32.png) [@pungent](https://discuss.elastic.co/u/pungent)\
**Post date:** [October 25, 2016, 5:30pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/3 "2016-10-25T17:30:03Z")

</div>

Sure @nik9000 , this is what I get:

```auto
{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 4,
    "failed": 1,
    "failures": [
      {
        "shard": 0,
        "index": "listings_v1",
        "node": "ce3vfaL765et7UXTD4ewQ",
        "reason": {
          "type": "query_parsing_exception",
          "reason": "script_score the script could not be loaded",
          "index": "listings_v1",
          "line": 15,
          "col": 17,
          "caused_by": {
            "type": "script_exception",
            "reason": "scripts of type [inline], operation [search] and lang [groovy] are disabled"
          }
        }
      }
    ]
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

```

FYI my elasticsearch.yml has this setting:

```auto
script.inline: true
script.indexed: true

```

I am using ES2.3. Please note my all other groovy queries work fine in `script_score`, only this one fails

---

<div class="post-metadata">

**Author:** ![pungent](https://avatars.discourse-cdn.com/v4/letter/p/a698b9/32.png) [@pungent](https://discuss.elastic.co/u/pungent)\
**Post date:** [October 25, 2016, 5:48pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/4 "2016-10-25T17:48:35Z")

</div>

It is weird that sometimes I get different error message saying  
`"reason": "missing_method_exception: No signature of method: java.util.HashMap.call() is applicable for argument types: (e59f5ff9a4ea5a82513a5a8e06fcc8269b487334$_run_closure1$_closure2) values: [e59f5ff9a4ea5a82513a5a8e06fcc8269b487334$_run_closure1$_closure2@6be9b69c]\nPossible solutions: wait(), any(), wait(long), any(groovy.lang.Closure), each(groovy.lang.Closure), max(groovy.lang.Closure)"`

---

<div class="post-metadata">

**Author:** ![pungent](https://avatars.discourse-cdn.com/v4/letter/p/a698b9/32.png) [@pungent](https://discuss.elastic.co/u/pungent)\
**Post date:** [October 25, 2016, 6:11pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/5 "2016-10-25T18:11:03Z")

</div>

By the way `"script": "doc['mygroup'].values....` \< i think I cannot use `doc` here. It should be `"script": "_source['mygroup'].values` per [ElasticSearch: access document nested value in groovy script](https://discuss.elastic.co/t/elasticsearch-access-document-nested-value-in-groovy-script/21644) ? Please let me knwo what do you think @nik9000

---

<div class="post-metadata">

**Author:** ![nik9000](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nik9000/32/44947_2.png) [@nik9000](https://discuss.elastic.co/u/nik9000)\
**Post date:** [October 25, 2016, 6:16pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/6 "2016-10-25T18:16:12Z")

</div>

So `_source` and `doc` should both be available, though I think to get the values for `doc` you'd need `doc['mygroup.start']` and `doc['mygroup.end']`. The reason is that doc processes things column wise whereas `_source` uses the source document. I expect `doc` to be much faster if processing a lot of data.

> scripts of type [inline], operation [search] and lang [groovy] are disabled

That makes me suspect at least one of your Elasticsearch nodes doesn't have inline scripts enabled. Those errors should appear in the logs - maybe you can look and find if it is just one node?

---

<div class="post-metadata">

**Author:** ![pungent](https://avatars.discourse-cdn.com/v4/letter/p/a698b9/32.png) [@pungent](https://discuss.elastic.co/u/pungent)\
**Post date:** [October 25, 2016, 6:20pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/7 "2016-10-25T18:20:25Z")

</div>

> [@nik9000](#):
>
> I think to get the values for doc you'd need doc['mygroup.start'] and doc['mygroup.end'].

Since I need to loop through `mygroup` object first to find the object that matches my condition, so  
`"script": "doc['mygroup.start'].values.any{.......... ` will not work, right?

Regardin `So _source and doc should both be available`  
`doc` it doesn't work, it only works with `_source`

---

<div class="post-metadata">

**Author:** ![nik9000](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nik9000/32/44947_2.png) [@nik9000](https://discuss.elastic.co/u/nik9000)\
**Post date:** [October 25, 2016, 6:36pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/8 "2016-10-25T18:36:52Z")

</div>

It should work with `doc`, just differently. More like  
`[doc['mygroup.start'], doc['mygroup.end']].transpose().any { [start, end] -> end >= desired && start <= desired) return (start - delta) * 2`

---

<div class="post-metadata">

**Author:** ![pungent](https://avatars.discourse-cdn.com/v4/letter/p/a698b9/32.png) [@pungent](https://discuss.elastic.co/u/pungent)\
**Post date:** [October 25, 2016, 6:52pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/9 "2016-10-25T18:52:45Z")

</div>

Thanks for your suggestion @nik9000

There was a minor typo in your snippet  
`[doc['mygroup.start'], doc['mygroup.end']].transpose().any { [start, end] -> end >= desired && start <= desired) return (start - delta) * 2`

changed to

`[doc['mygroup.start'], doc['mygroup.end']].transpose().any { [start, end] -> end >= desired && start <= desired} return (start - delta) * 2`

then the error is

`"reason": { "type": "query_parsing_exception", "reason": "script_score the script could not be loaded", "index": "listings_v1", "line": 15, "col": 17, "caused_by": { "type": "script_exception", "reason": "[doc['mygroup.start'], doc['mygroup.end']].transpose().any { [start, end] -> end >= desired && start <= desired} return (start - delta) * 2", "caused_by": { "type": "script_exception", "reason": "failed to compile groovy script", "caused_by": { "type": "multiple_compilation_errors_exception", "reason": "multiple_compilation_errors_exception: startup failed:\n7b2778accce04239f1cc125c4f6467f97c82295f: 1: expecting '}', found '->' @ line 1, column 89.\n ranspose().any { [start, end] -> end\n ^\n\n1 error\n" } } } }`

---

<div class="post-metadata">

**Author:** ![nik9000](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nik9000/32/44947_2.png) [@nik9000](https://discuss.elastic.co/u/nik9000)\
**Post date:** [October 25, 2016, 7:07pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/10 "2016-10-25T19:07:05Z")

</div>

Sorry! I'm not really a groovy expert and I just wrote it without trying it against anything. I expect there is a syntax error when I destructure the list around `[start, end]`. I thought it worked like that but I think it should instead be `(start, end)`. Something like that ought to work for you though.

---

<div class="post-metadata">

**Author:** ![pungent](https://avatars.discourse-cdn.com/v4/letter/p/a698b9/32.png) [@pungent](https://discuss.elastic.co/u/pungent)\
**Post date:** [October 25, 2016, 7:20pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/11 "2016-10-25T19:20:24Z")

</div>

Thanks @nik9000 for your persistency to unblock me ...really appreciated. See thsi is what I get as error:

![](https://us1.discourse-cdn.com/elastic/original/2X/c/cd95d52c918c65f410dae6243906439bca0e26d1.png)

---

<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:** [July 5, 2017, 10:09pm UTC](https://discuss.elastic.co/t/groovy-script-to-iterate-through-nested-object-for-scoring-throws-error/63904/12 "2017-07-05T22:09:49Z")

</div>


