我有一个带有嵌套字段“角色”的elasticsearch索引:
"roles": {
"type": "nested",
"properties": {
"name": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keylower"
}
}
},
"responsibilities": {
"properties": {
"name": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keylower"
}
}
}
}
}
}
}
这些字段中的值是数组,例如:
"roles": [
{
"name": "System Analyst",
"responsibilities": [
{
"name": "Software Development"
},
{
"name": "Software Testing"
}
]
},
{
"name": "Data Analyst",
"responsibilities": [
{
"name": "Data analysis"
},
{
"name": "Reporting"
}
]
}
]
我想分别在这些字段上构建 Kibana 可视化。由于它是一个嵌套字段,而 kibana 还不支持它(?),我想到为每个字段创建运行时字段。
这是我用于角色的查询:
PUT employee/_mappings
{
"runtime": {
"empRoles": {
"type": "keyword",
"script": """if (doc["roles.name.raw"].size()!=0 ) {
String[] empRoles;
for(int i=0; i < doc["roles.name.raw"].size(); i++) {
empRoles[i] = doc["roles.name.raw"].value ;
}
emit(empRoles);}"""
}
}
}
但是我收到以下错误:
"caused_by" : {
"type" : "class_cast_exception",
"reason" : "Cannot cast from [java.lang.String[]] to [java.lang.String]."
}
我怎样才能让它发挥作用?最终,我想在“角色”和“职责”字段上构建一个 kibana 仪表板。
似乎无法将
nested
字段与 runtime
字段一起使用。
我可以通过定义一个脚本字段来获得所需的结果,如建议的这里。
在
Index Pattern > [index pattern name] > Scripted fields tab > Add scripted field
添加以下脚本(Kibana 版本 7.17。对于更高版本,请将 Index Patterns
替换为 Data Views
)。
对于
roles
:
def names = new String[params._source.roles.length];
def i= 0;
for( role in params._source.roles){
if(role.name != null){
names[i++] = role.name;
}
}
return names;
对于
responsibilities
:
def responsibilitiesLength = 0;
for( role in params._source.roles){
responsibilitiesLength += role.responsibilities.length;
}
def responsibilities = new String[responsibilitiesLength];
def i= 0;
for( role in params._source.roles){
for( responsability in role.responsibilities){
responsibilities[i++] = responsability.name
}
}
return responsibilities;
(注意:脚本化字段可能会导致性能问题,因此已被弃用)
您认为同样的解决方案也适用于扁平化区域吗?我们最近不得不从嵌套类型转向扁平类型,因为它使用的空间要少得多。扁平化字段存储嵌套的 JSON,但我尚未成功为运行时字段创建一个有效的轻松脚本。