Using Scripted field to display a sub-string

Hello. We are using ELK 7.6.2 stack.

I have a field named host.name which displays a value such as ad-c2ff-v2bg.taz.root.net

I need to extract the second substring (taz) using Scripted field. When I try to define a new scripted field named region and put the following script in Kibana console, I get classcast exception:

doc['host.name.keyword'].split('.')[1]

I am new to Scripted fields.

Please guide

first, to avoid issues, make sure the value you are calling has content, otherwise it will screw up all your data view:

I think this should do the trick for you :slight_smile:

if (doc['host.name.keyword'].size() == 0) {
  emit ("N/A"); //put whatever you want here to notify the runtime field does not have a value
} else {
  String[] hostNameKeyword = doc['host.name.keyword'].value.splitOnToken('.');
  emit (hostNameKeyword[1])
}

Thanks @msanz-acclaro

I see compilation errors. Looks like its not happy with emit.

"reason": "Unknown call [emit] with [1] arguments."

Please see the complete error below:

{
 "root_cause": [
  {
   "type": "script_exception",
   "reason": "compile error",
   "script_stack": [
    "... word'].size() == 0) {\r\n  emit (\"hostname not prese ...",
    "                             ^---- HERE"
   ],
   "script": "if (doc['host.name.keyword'].size() == 0) {\r\n  emit (\"hostname not present\"); \r\n} else {\r\n  String[] hostNameKeyword = doc['host.name.keyword'].value.splitOnToken('.');\r\n  emit (hostNameKeyword[1])\r\n}",
   "lang": "painless"
  }
 ],
 "type": "search_phase_execution_exception",
 "reason": "all shards failed",
 "phase": "query",
 "grouped": true,
 "failed_shards": [
  {
   "shard": 0,
   "index": "uat_tv_gclog_analysis-2022.07.28",
   "node": "8kBsCXf3SnmpxLv0m-CRhA",
   "reason": {
    "type": "script_exception",
    "reason": "compile error",
    "script_stack": [
     "... word'].size() == 0) {\r\n  emit (\"hostname not prese ...",
     "                             ^---- HERE"
    ],
    "script": "if (doc['host.name.keyword'].size() == 0) {\r\n  emit (\"hostname not present\"); \r\n} else {\r\n  String[] hostNameKeyword = doc['host.name.keyword'].value.splitOnToken('.');\r\n  emit (hostNameKeyword[1])\r\n}",
    "lang": "painless",
    "caused_by": {
     "type": "illegal_argument_exception",
     "reason": "Unknown call [emit] with [1] arguments."
    }
   }
  }
 ]
}

I dont really know what the problem might be, seems that there are errors in your script. Try this example:

String hostnameTest = "hello.second.third.etc";
String[] hostnameTestArray = hostnameTest.splitOnToken('.');
emit(hostnameTestArray[1]);

0 = hello
1 = second
2 = third
4 = etc
5 < = error

HTH :slight_smile:

oh try to change emit by return you are using legacy "scripted fields".

Try the runtime fields: Getting started with runtime fields, Elastic’s implementation of schema on read | Elastic Blog in the future :slight_smile:

@msanz-acclaro

Thanks.

I was able to compile with return in place of emit. I find "region" field blank now. See below

The script looks like below:

if (doc['host.name.keyword'].size() == 0) {
  return ("host not available"); 
} else {
  String[] hostNameKeyword = doc['host.name.keyword'].value.splitOnToken('.');
  return (hostNameKeyword[1])
}

host.name field shows as ad-0851-a579.taz.root.net and in response "region" is expected as "taz"

Could it be that it is getting confused with a dot in the fieldname when used with keyword.

So host(dot)name(dot)keyword could lead it to mis-interpret?

@msanz-acclaro Thanks a lot for helping out.

Found the solution which was a typo as I retyped the (dot) value.splitOnToken('.') and now it works fine :slight_smile:

if (doc['host.name.keyword'].size() == 0) {
  return ("host not available"); 
} else {
  String[] hostNameKeyword = doc['host.name.keyword'].value.splitOnToken('.');
  return (hostNameKeyword[1])
}
1 Like

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