Scripted fields throwing error

I have few scripted fields which are causing error post migrations from 5x to 7.0.0.

Then i noticed in breaking changes that i need to include a check like below to confirm if the fields exist:

A document doesn't have a value for a field! Use doc[<field>].size()==0 to check if a document is missing a field!

My script:

if (doc['key1'].size() == 0 || doc['key2'].size() == 0 || doc['key3'].size() == 0) {
  return ''
}
return (doc['key1'].value + doc['key2'].value + doc['key3'].value ) /3

But when i did that, i started getting different error like below:

Caused by: org.elasticsearch.script.ScriptException: runtime error
        at org.elasticsearch.painless.PainlessScript.convertToScriptException(PainlessScript.java:94) ~[?:?]
        at org.elasticsearch.painless.PainlessScript$Script.execute(if (doc['key1'].size() == 0 && doc['key2'].size() == 0 && doc['key3:569) ~[?:?]
        at org.elasticsearch.search.fetch.subphase.ScriptFieldsFetchSubPhase.hitsExecute(ScriptFieldsFetchSubPhase.java:67) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.fetch.FetchPhase.execute(FetchPhase.java:177) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.SearchService.lambda$executeFetchPhase$3(SearchService.java:540) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.SearchService$3.doRun(SearchService.java:380) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.TimedRunnable.doRun(TimedRunnable.java:41) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:751) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-7.0.0.jar:7.0.0]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[?:?]
        at java.lang.Thread.run(Thread.java:835) [?:?]
Caused by: java.lang.IllegalArgumentException: No field found for [key1] in mapping with types []
        at org.elasticsearch.painless.PainlessScript$Script.execute(if (doc['key1'].size() == 0 || doc['key2'].size() == 0 && doc['key3...:9) ~[?:?]
        at org.elasticsearch.search.fetch.subphase.ScriptFieldsFetchSubPhase.hitsExecute(ScriptFieldsFetchSubPhase.java:67) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.s
        at org.elasticsearch.search.SearchService$3.doRun(SearchService.java:380) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:751) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-7.0.0.jar:7.0.0]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[?:?]
        at java.lang.Thread.run(Thread.java:835) ~[?:?]

then i tried with using doc.containsKey to check if field exists, but again started getting error like below:

Caused by: org.elasticsearch.script.ScriptException: runtime error
        at org.elasticsearch.painless.PainlessScript.convertToScriptException(PainlessScript.java:94) ~[?:?]
        at org.elasticsearch.painless.PainlessScript$Script.execute(if (doc.containsKey('key1') && doc.containsKey('key2') && doc.containsKey(key3) ~[?:?]
        at org.elasticsearch.search.fetch.subphase.ScriptFieldsFetchSubPhase.hitsExecute(ScriptFieldsFetchSubPhase.java:67) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.fetch.FetchPhase.execute(FetchPhase.java:177) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.SearchService.lambda$executeFetchPhase$3(SearchService.java:540) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.SearchService$3.doRun(SearchService.java:380) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.TimedRunnable.doRun(TimedRunnable.java:41) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:751) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-7.0.0.jar:7.0.0]
        at java.lang.Thread.run(Thread.java:835) [?:?]
Caused by: java.lang.IllegalStateException: A document doesn't have a value for a field! Use doc[<field>].size()==0 to check if a document is missing a field!
        at org.elasticsearch.index.fielddata.ScriptDocValues$Longs.get(ScriptDocValues.java:121) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.index.fielddata.ScriptDocValues$Longs.getValue(ScriptDocValues.java:115) ~[elasticsearch-7.0.0.jar:7.0.0]
        at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:719) ~[?:?]
        at org.elasticsearch.painless.DefBootstrap$PIC.fallback(DefBootstrap.java:216) ~[?:?]
        at org.elasticsearch.painless.PainlessScript$Script.execute(if (doc.containsKey('key1') && doc.containsKey('key2') && doc.containsKey('key3') ~[?:?]
        at org.elasticsearch.search.fetch.subphase.ScriptFieldsFetchSubPhase.hitsExecute(ScriptFieldsFetchSubPhase.java:67) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.fetch.FetchPhase.execute(FetchPhase.java:177) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.SearchService.lambda$executeFetchPhase$3(SearchService.java:540) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.search.SearchService$3.doRun(SearchService.java:380) ~[elasticsearch-7.0.0.jar:7.0.0]
        at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:751) ~[elasticsearch-7.0.0.jar:7.0.0]

What's the correct way to perform this check? And why it might be failing?

Thanks.

It looks as if ElasticSearch was trying to find the field "key1" in the index mapping. Can you check that the field is in the mapping definition?

Thanks for the quick reply @Wolfram_Haussig

Yes the field is in mapping definition of the index.

Than I have no idea what is happening as I do not use scripted fields but I am sure some ElasticSearch expert can help you

Sure, Does it have anything to do with field actually appearing as key.key1? in mapping it appears as:

"key" : {
          "key1"
           "key2"
           "key3"
}

And in my script i access them as key.key1 and so on..

Is it required that all three fields should be in same document?

Yes. Scripts are ru in the context of a single document.

Thanks. But still I'm not able to get the script to work even though all three fields are present in my documents.

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