elasticsearch无痛访问动态命名字段

时间:2018-03-01 09:39:16

标签: elasticsearch elasticsearch-painless

我试图在弹性搜索中平均一个字段,

"aggs": {
      "avg_timedifference": {
         "avg": {
            "script" : "doc['@timestamp'].value"
         }
      }

这有效,

映射的位置,

    {
            "_index" : "justchill",
            "_type" : "doc",
            "_id" : "cRP1bWEB6Z3gZHtPaXv1",
            "_score" : 1.0,
            "_source" : {

              "port" : 80,
              "bing.sss-ccc.tc.DOWNSTREAM_dropped.bong" : 33.0,
              "@timestamp" : "2018-02-07T01:50:55.000Z",
              "message" : "ccc.dna-ccc.tc.DOWNSTREAM_dropped.kkk 33 1517968255",
              "@version" : "1",
              "host" : "localhost"
            }
          },
          {
            "_index" : "justchill",
            "_type" : "doc",
            "_id" : "cRP1bWEB6Z3gZHtPaXv1",
            "_score" : 1.0,
            "_source" : {

              "port" : 80,
              "bong.sss-ccc.tc.DOWNSTREAM_dropped.bing" : 33.0,
              "@timestamp" : "2018-02-07T01:50:55.000Z",
              "message" : "ccc.dna-ccc.tc.DOWNSTREAM_dropped.kkk 33 1517968255",
              "@version" : "1",
              "host" : "localhost"
            }
          },

我想要做的是访问这里临时名为bing..bong和bong ..bing的字段。该字段是动态映射的,以任何方式访问它?

1 个答案:

答案 0 :(得分:0)

您可以通过params._source(原文如此)以Java Map的形式访问所有源。

这反过来使您可以查找通过keySet()方法显示的键,并且可以找出字段的确切名称。

在您的示例中,您将获得类似以下脚本的内容:

for (field in params._source.keySet()) {
  if (field.startsWith('bong')) {
    return doc[field+'.keyword']
  }
}
return 'No field found matching bong'

这只是一个基本设置;是否需要指定是否要由您自己决定关键字,此解决方案只会采用第一个匹配项。

请注意,如果您要查看多层字段,则不能仅使用点来查看params._source。例如,如果您想返回子域 connection host 下的所有域,以及子域以ip 开头的子域,则需要{ {1}}

不幸的是,这种方法是否有效还取决于上下文。据我测试,它可以在聚合和脚本字段中使用,但不能在脚本查询中使用。

最后,请注意,“参数” for (field in params._source['host']['connection'].keySet())是一种自动参数,无需在_source下指定任何内容

记录在案:我知道我来晚了,但是偶然发现了这个问题myzelf,答案可能对其他仍在寻找的人有用。