如何在elasticsearch中基于嵌套字段创建数组类型运行时字段?

问题描述 投票:0回答:2

我有一个带有嵌套字段“角色”的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 仪表板。

elasticsearch kibana elasticsearch-painless nested-fields
2个回答
0
投票

似乎无法将

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;

(注意:脚本化字段可能会导致性能问题,因此已被弃用)


0
投票

您认为同样的解决方案也适用于扁平化区域吗?我们最近不得不从嵌套类型转向扁平类型,因为它使用的空间要少得多。扁平化字段存储嵌套的 JSON,但我尚未成功为运行时字段创建一个有效的轻松脚本。

© www.soinside.com 2019 - 2024. All rights reserved.