我有一个字符串字段“myfield.keyword”,其中条目具有以下格式:
AAA_BBBB_CC
DDD_EEE_F
我正在尝试创建一个输出第一个 _ 之前的子字符串的脚本化字段、一个输出第一个和第二个 _ 之间的子字符串的脚本化字段以及一个输出第二个 _ 之后的子字符串的脚本化字段。
我尝试使用 .split('_') 来执行此操作,但发现此方法在 Painless 中不可用:
def newfield = "";
def path = doc[''myfield.keyword].value;
if (...)
{newfield = path.split('_')[1];} else {newfield="null";}
return newfield
然后我尝试了here建议的解决方法,但发现我必须在 Elastic 中启用正则表达式(这在我的情况下是不可能的):
def newfield = "";
def path = doc[''myfield.keyword].value;
if (...)
{newfield = /_/.split(path)[1];} else {newfield="null";}
return newfield
有没有一种方法可以做到这一点,前提是启用正则表达式?
编辑:
感谢您提供如此优雅的解决方案 Val。这回答了我问的问题。然而,我的问题格式不完善。特别是,需要拆分的字符串出现了四次“_”。比如:
AAA_BB_CCC_DD_E
FFF_GGG_HH_JJJJ_KK
所以,如果我理解正确的话,
indexOf()
和lastIndexOf()
不能给我BB,CCC或DD。我认为我可以调整您的解决方案,并通过使用 string.indexOf("_", 1)
和 string.indexOf("_", 2)
找到第二次和第三次出现 _ 的索引。然而,我总是得到与 string.indexOf("_")
相同的结果,没有任何额外的参数(即结果始终是 _ 第一次出现的索引)。
启用正则表达式并不是非常复杂,但它需要重新启动集群,并且根据环境的不同,这对您来说可能并不容易。
实现这一目标的另一种方法是采用“旧方法”。首先,为每个脚本字段创建一个可重用脚本。该脚本所做的只是找到第一次、第二次、第三次和最后一次出现的
_
符号并返回分割元素。它将要分割的字段名称和要返回的子字符串的索引作为输入:
POST _scripts/my-split
{
"script": {
"lang": "painless",
"source": """
def str = doc[params.field].value;
def first = str.indexOf("_");
def second = first + 1 + str.substring(first + 1).indexOf("_");
def third = second + 1 + str.substring(second + 1).indexOf("_");
def last = str.lastIndexOf("_");
def parts = [
str.substring(0, first),
str.substring(first + 1, second),
str.substring(second + 1, third),
str.substring(third + 1, last),
str.substring(last + 1)
];
return parts[params.index];
"""
}
}
然后您可以简单地为每个部分定义一个脚本字段,如下所示:
POST test/_search
{
"script_fields": {
"first": {
"script": {
"id": "my-split",
"params": {
"field": "myfield.keyword",
"index": 0
}
}
},
"second": {
"script": {
"id": "my-split",
"params": {
"field": "myfield.keyword",
"index": 1
}
}
},
"third": {
"script": {
"id": "my-split",
"params": {
"field": "myfield.keyword",
"index": 2
}
}
}
}
}
您收到的回复将如下所示:
{
"_index" : "test",
"_type" : "_doc",
"_id" : "ykS-l3UBeO1HTBdDvTZd",
"_score" : 1.0,
"fields" : {
"first" : [
"AAA"
],
"second" : [
"BBBB"
],
"third" : [
"CC"
]
}
}
您可以使用
str.splitOnToken("_")
并将每个结果作为数组检索,并出于任何目的循环该数组。
您甚至可以拆分可变标记,例如:
def message = "[LOG] Something something WARNING: Your warning";
def reason = message.splitOnToken("WARNING: ")[1];
因此,reason 将保留剩余的字符串:
Your warning
。
完成“George Ts.”伟大的答案...
这对我来说很方便,带有定界符“-”的语法,甚至在 Opensearch-dashboards
String[] message = message.splitOnToken("-");
// Return the first part if it exists
if (message.length > 1) {
return message[0]; // Adjust index as needed
} else {
return 'empty';
}