遍历数组的Kibana脚本字段

时间:2019-06-20 15:00:11

标签: elasticsearch kibana metricbeat

我正在尝试使用metricbeat http模块监视F5池。

我向f5 api请求并带回json,并将其保存到kibana。但是json包含一个池成员数组,我想计算增加的​​数量。

建议似乎可以使用脚本字段完成此操作。但是,我无法获取脚本来检索数组。例如

doc['http.f5pools.items.monitor'].value.length()

返回预览结果并添加相同的“其他字段”以进行比较:

[
 {
  "_id": "rT7wdGsBXQSGm_pQoH6Y",
  "http": {
   "f5pools": {
    "items": [
     {
      "monitor": "default"
     },
     {
      "monitor": "default"
     }
    ]
   }
  },
  "pool.MemberCount": [
   7
  ]
 },

如果我尝试

doc['http.f5pools.items']

或类似的错误消息:

"reason": "No field found for [http.f5pools.items] in mapping with types []"

Google搜索表明doc构造不包含数组吗?

  1. 是否可以创建一个可以访问值集的脚本字段?即是我的代码还是错误地为数据建立索引的方式。
  2. 在metricbeats中是否没有其他方法?我不想制作一个全新的api来进行计算并添加一个单独的字段

-更新。

奇怪的是,似乎数组中的数字值确实返回了预期的结果。即。

doc['http.f5pools.items.ratio']

返回

 {
  "_id": "BT6WdWsBXQSGm_pQBbCa",
  "pool.MemberCount": [
   1,
   1
  ]
 },

-更新2

好,因此,如果字段中的字符串具有不同的值,那么您将获得所有值。如果它们相同,您将得到一个。 wtf?

3 个答案:

答案 0 :(得分:1)

我要添加另一个答案,而不是删除之前的答案,这不是实际问题,但将来可能会对其他人有所帮助。

我在same documentation中发现了一个提示:

  

文档值是列式字段值存储区

进一步查询之后,我发现Doc Value Intro表示文档值本质上是“未反转的索引”,对诸如排序之类的操作很有用;我的假设是,在排序时,您基本上不希望重复相同的值,因此,他们使用的数据结构会删除这些重复项。对于字符串为什么与数字不同的工作,那仍然没有答案。数字被保留,但字符串被过滤为唯一。

  

在其他情况下,这种“未反转”的结构通常称为“列存储”   系统。本质上,它存储单个字段的所有值   一起放在一个数据列中,这对于   排序等操作。

     

在Elasticsearch中,此列存储称为doc值,并且为   默认情况下启用。在索引时间创建文档值:当字段   被索引后,Elasticsearch将令牌添加到反向索引中   搜索。但它也会提取术语并将其添加到柱状   文档值。

更多deep-dive into doc values revealed it a compression technique实际上消除了重复值的重复,从而实现了高效且对内存友好的操作。

在上面的链接中提供了一个注释,可以回答问题:

  

您可能会想:“这对数字很有用,但那又如何呢?   字符串?”在序数的帮助下,字符串的编码方式类似   表。 字符串已删除重复,并排序到一个表中,并分配了   ID,然后将这些ID用作数字文档值。意思是   字符串具有许多与数字相同的压缩优势。

     

序表本身具有一些压缩技巧,例如使用   固定,可变或前缀编码的字符串。

此外,如果您不希望出现这种情况,则可以disable doc-values

答案 1 :(得分:0)

好,解决了。

https://discuss.elastic.co/t/problem-looping-through-array-in-each-doc-with-painless/90648

因此,正如我发现的那样,对数组进行了预过滤以仅返回不同的值(显然是int的情况除外)。

解决方案是使用.clickme代替params._source

答案 2 :(得分:0)

The answer for why doc doesnt work

引用如下:

  

Doc值是列式字段值存储,默认情况下,所有   字段,但分析的文本字段除外。

     

文档值只能返回“简单”字段值,例如数字,日期,   地理位置,术语等或这些值的数组(如果该字段为   多值。它无法返回JSON对象

此外,如下所述添加空检查很重要:

  

缺少字段

     

如果field为,则doc ['field']将引发错误   映射中缺少。在无痛的情况下,可以先检查一下   doc.containsKey('field')*来保护对文档映射的访问。   不幸的是,没有办法检查该字段的存在   在表达式脚本的映射中。

Also, here is why _source works

引用如下:

  

_source文件实际上只是一个特殊的存储字段,可以   可以使用_source.field_name语法进行访问。 _source已加载   作为地图的地图,因此可以访问对象字段中的属性   例如_source.name.first。

使用示例回复您的评论

这里的关键词是: 它不能返回JSON对象 。字段doc ['http.f5pools.items']是 JSON对象

尝试在下面运行,查看其创建的映射:

PUT t5/doc/2
{
   "items": [
     {
      "monitor": "default"
     },
     {
      "monitor": "default"
     }
    ]
}


GET t5/_mapping

{
  "t5" : {
    "mappings" : {
      "doc" : {
        "properties" : {
          "items" : {
            "properties" : {
              "monitor" : {  <-- monitor is a property of items property(Object)
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}