# Create Scripted Field using substring before "."

**URL:** <https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096>\
**Category:** Kibana\
**Created:** [June 22, 2020, 1:45pm UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096 "2020-06-22T13:45:32Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![giacman](https://avatars.discourse-cdn.com/v4/letter/g/f07891/32.png) [@giacman](https://discuss.elastic.co/u/giacman)\
**Post date:** [June 22, 2020, 1:45pm UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/1 "2020-06-22T13:45:32Z")

</div>

I'm trying to create a Scripted Field for a dashboard in Kibana.

My original field is called `topic` and has the following values, as an example:

```
    a
    b
    a.c
    b.f
    a.c.d
    b.e.t

```

I would like to build a `root.topic` field that is either `a` or `b`, depending on the substring before the dot.

I have tried this:

`doc['topic.keyword'].split('.')[0]` but the preview tab shows an empty list `[]` as a result.

Could anyone please point me in the right direction?

---

<div class="post-metadata">

**Author:** ![aaron-nimocks](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aaron-nimocks/32/73965_2.png) [@aaron-nimocks](https://discuss.elastic.co/u/aaron-nimocks)\
**Post date:** [June 22, 2020, 1:48pm UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/2 "2020-06-22T13:48:27Z")

</div>

Did you check the results in Discovery to see if it's working? I haven't had much luck with the preview tab with the exception of showing errors or not. The data preview part doesn't seem consistent.

---

<div class="post-metadata">

**Author:** ![giacman](https://avatars.discourse-cdn.com/v4/letter/g/f07891/32.png) [@giacman](https://discuss.elastic.co/u/giacman)\
**Post date:** [June 22, 2020, 2:03pm UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/3 "2020-06-22T14:03:58Z")

</div>

Hi Aaron,

thanks a lot for your quick reply.

I get this error "Unable to write index pattern! Refresh the page to get the most up to date changes for this index pattern." and the Create Field object keeps spinning.

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/b/6/b6592f1b6600bde1f9b0026966664b14f06cfa9e.png)

I have also found theses articles that seems similar:

> [@Scripted Field: getting first index of a substring](https://discuss.elastic.co/t/scripted-field-getting-first-index-of-a-substring/81418/2):
>
> I'm not a painless expert, but [here is the API](https://www.elastic.co/guide/en/elasticsearch/reference/current/painless-api-reference.html). You already know the index of the last / from the use of lastIndexOf, and you're already using substring. If you give [substring](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#substring%2Dint%2Dint%2D) 2 arguments, it'll use the first one as the start and the last one as the end, non-inclusive. So, in your case, this should give you the content before the last / - return path.substring(0, lastSlashIndex); def path = doc['string\_value.keyword'].value; if (path != null) { int lastSlashIndex = path.lastIndexOf('/'); if (…

> [@ScriptedField - Only part before comma is taken](https://discuss.elastic.co/t/scriptedfield-only-part-before-comma-is-taken/85885):
>
> I added a scripted field to my index with name Drift using painless: Name Language Script Drift painless doc['NumberValue'].value The attribute NumberValue has float values. The scripted field shows only the part before the comma [image] When I do the same with another float attribute the scripted field shows the hole float number. How can I troubleshoot this error? Thank you for your support

But I couldn't make it work. Any help would be greatly appreciated!

---

<div class="post-metadata">

**Author:** ![aaron-nimocks](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aaron-nimocks/32/73965_2.png) [@aaron-nimocks](https://discuss.elastic.co/u/aaron-nimocks)\
**Post date:** [June 22, 2020, 2:12pm UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/4 "2020-06-22T14:12:45Z")

</div>

Does every row of data contain a period? In your example you show 2 that don't. The split function might throw some errors if you are trying to split something that doesn't have a period.

If so, would need to do a check first to see if it contains a period and then do the split.

Also might trying to refresh your index pattern.

---

<div class="post-metadata">

**Author:** ![giacman](https://avatars.discourse-cdn.com/v4/letter/g/f07891/32.png) [@giacman](https://discuss.elastic.co/u/giacman)\
**Post date:** [June 23, 2020, 8:58am UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/5 "2020-06-23T08:58:12Z")

</div>

Hi Aaron,

thanks for your support.

```
def topic = doc['topic.keyword'].value;
if (topic.contains(".")) {
root = topic.split(".")[0]
return root;
}
return topic;

```

but still can't make it work. I get this error:

There's an error in your script

```auto
{
 "root_cause": [
  {
   "type": "script_exception",
   "reason": "compile error",
   "script_stack": [
    "... ot = topic.split(\".\")[0]\nreturn root;\n}\nreturn top ...",
    " ^---- HERE"
   ],
   "script": "def topic = doc['topic.keyword'].value;\nif (topic.contains(\".\")) {\nroot = topic.split(\".\")[0]\nreturn root;\n}\nreturn topic;",
   "lang": "painless"
  }
 ],
 "type": "search_phase_execution_exception",
 "reason": "all shards failed",
 "phase": "query",
 "grouped": true,
 "failed_shards": [
 
   ....

```

Any help would be greatly appreciated, thanks!

---

<div class="post-metadata">

**Author:** ![aaron-nimocks](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aaron-nimocks/32/73965_2.png) [@aaron-nimocks](https://discuss.elastic.co/u/aaron-nimocks)\
**Post date:** [June 23, 2020, 10:15am UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/6 "2020-06-23T10:15:19Z")

</div>

Untested but I'd try this.

```auto
String str = doc['topic.keyword'].value;
if (str.contains(".")) {
String[] arrOfStr = topic.split(".");
return arrOfStr[0];
}
return str;

```

---

<div class="post-metadata">

**Author:** ![giacman](https://avatars.discourse-cdn.com/v4/letter/g/f07891/32.png) [@giacman](https://discuss.elastic.co/u/giacman)\
**Post date:** [June 23, 2020, 10:49am UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/7 "2020-06-23T10:49:09Z")

</div>

Hi Aaron,

again thanks for your help. I tried your solution but it doesn't work:

```
 "root_cause": [
  {
   "type": "script_exception",
   "reason": "compile error",
   "script_stack": [
    "... )) {\nString[] arrOfStr = topic.split(\".\");\nreturn ...",
    " ^---- HERE"
   ],
   "script": "String str = doc['topic.keyword'].value;\nif (str.contains(\".\")) {\nString[] arrOfStr = topic.split(\".\");\nreturn arrOfStr[0];\n}\nreturn str;",
   "lang": "painless"
  }
 ],
 "type": "search_phase_execution_exception",
 "reason": "all shards failed",
 "phase": "query",
 "grouped": true,

```

I have also used your suggested approach and tried this

```
def topic = doc['topic.keyword'].value;
if (topic.contains('.')) {
    String[] fragments = topic.split('.');
	if (fragments.length > 0 ) {
String root = fragments[0];
		return root;
	}
}
return topic;

```

But I get the empty set `[]` as a result.

🙏 Thanks for your help 🙏

---

<div class="post-metadata">

**Author:** ![aaron-nimocks](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aaron-nimocks/32/73965_2.png) [@aaron-nimocks](https://discuss.elastic.co/u/aaron-nimocks)\
**Post date:** [June 23, 2020, 11:01am UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/8 "2020-06-23T11:01:56Z")

</div>

```auto
String str = doc['topic.keyword'].value;
if (str.contains(".")) {
String[] arrOfStr = str.split(".");
return arrOfStr[0];
}
return str;

```

I had TOPIC where STR should be. Try above.

---

<div class="post-metadata">

**Author:** ![aaron-nimocks](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aaron-nimocks/32/73965_2.png) [@aaron-nimocks](https://discuss.elastic.co/u/aaron-nimocks)\
**Post date:** [June 23, 2020, 11:07am UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/9 "2020-06-23T11:07:39Z")

</div>

> [@Using painless split function in aggregation](https://discuss.elastic.co/t/using-painless-split-function-in-aggregation/153168):
>
> Hello, I am trying to use the painless script split function in my AWS elasticsearch cluster but it does not seem to be working. I get "Unable to find dynamic method [split] with [1] arguments for class [java.lang.String]." Any idea? Many thanks

Ok, looked it up. Apparently you can't use split. Need to use REGEX or another method.

---

<div class="post-metadata">

**Author:** ![aaron-nimocks](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aaron-nimocks/32/73965_2.png) [@aaron-nimocks](https://discuss.elastic.co/u/aaron-nimocks)\
**Post date:** [June 23, 2020, 11:19am UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/10 "2020-06-23T11:19:30Z")

</div>

So it looks like the below should work.

```auto
String str = doc['name.keyword'].value;
if (str.contains(".")) {
    String[] result = /./.split(str);
    return result[0];
}
return str;

```

But it leads to the error below. So if you're going down this route you might need to make those changes or wait for someone else who might know an easier way.

```auto
     "reason": "Regexes are disabled. Set [script.painless.regex.enabled] to [true] in elasticsearch.yaml to allow them. Be careful though, regexes break out of Painless's protection against deep recursion and long loops."

```

---

<div class="post-metadata">

**Author:** ![giacman](https://avatars.discourse-cdn.com/v4/letter/g/f07891/32.png) [@giacman](https://discuss.elastic.co/u/giacman)\
**Post date:** [June 25, 2020, 12:20pm UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/11 "2020-06-25T12:20:12Z")

</div>

HI Aaron, thanks for your help.

I will leave this thread open in the hope that someone from ES/Kibana could shed some light on this.

Being able to split string fields it's a pretty basic and important feature that should be provided within Kibana.

Thanks  
Giacomo

---

<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 23, 2020, 12:20pm UTC](https://discuss.elastic.co/t/create-scripted-field-using-substring-before/238096/12 "2020-07-23T12:20:24Z")

</div>

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