获取索引上的字段数

Fai*_*iry 9 elasticsearch logstash

出于优化目的,我试图减少总场数.然而,在我要做之前,我想知道我实际拥有多少个字段._stats端点中似乎没有任何信息,我无法弄清楚迁移工具如何进行其字段计数计算.

是否有某种方法,无论是使用端点还是通过其他方式,来获取指定索引的总字段数?

Val*_*Val 28

为了进一步构建其他答案所提供的内容,您可以获取映射,然后只计算关键字type在输出中出现的次数,这给出了字段数,因为每个字段都需要一个类型:

curl -s -XGET localhost:9200/index/_mapping?pretty | grep type | wc -l
Run Code Online (Sandbox Code Playgroud)

  • @Val 一个字段可以有多个“类型”:例如“datapath-id”:{“fields”:{“keyword”:{“ignore_above”:256,“type”:“keyword”}},“type” : “文本” } (3认同)
  • @BaZZiliO 现在可能,但在贡献答案时“_field_caps” API 不可用。 (2认同)

Fre*_*red 18

你可以试试这个:

curl -s -XGET "http://localhost:9200/index/_field_caps?fields=*" | jq '.fields|length'
Run Code Online (Sandbox Code Playgroud)

  • 在我看来,这是正确的答案,而不是公认的答案。 (4认同)
  • 免责声明:当提供接受的答案时,`_field_caps` API 不存在。另外,请注意,计算“_fields.length”不足以了解字段的数量,因为也可以有子字段 (3认同)

Mat*_*out 8

这只是一种无需编写脚本即可在Kibana 中获得相对估计值的快速方法(我不认为这是 100% 精确的,但这是一种判断动态字段是否因某种原因激增至巨大数字的简单方法)。

在 Kibana 开发工具中运行此查询

GET /index_name/_mapping

在 Kibana 输出中,搜索所有实例"type"(包括引号)。这将计算实例并为您提供答案。(在本例中为 804)

在此处输入图片说明

如果您摸不着头脑,为什么会出现以下[remote_transport_exception]错误,这可能会有所帮助

Limit of total fields [1000] in index [index_name] has been exceeded


Sau*_*ani 6

瓦尔的第一个回答也为我解决了这个问题。但我只是想列出一些可能导致误导性数字的极端情况。

  1. 该文档包含带有“类型”一词的字段。

例如

 "content_type" : {
   "type" : "text",
     "fields" : {
       "keyword" : {
          "type" : "keyword",
       }
     }
   },
Run Code Online (Sandbox Code Playgroud)

这将匹配grep type三次,而它应该只匹配两次,即它不应该匹配“content_type”。这种情况很容易解决。

代替

curl -s -XGET localhost:9200/index/_mapping?pretty | grep type 
Run Code Online (Sandbox Code Playgroud)

使用

curl -s -XGET localhost:9200/index/_mapping?pretty | grep '"type"'
Run Code Online (Sandbox Code Playgroud)

获得“type”的精确匹配

  1. 该文档有一个名称为“type”的字段

例如

"type" : {
  "type" : "text",
   "fields" : {
     "keyword" : {
       "type" : "keyword"
     }
   }
},
Run Code Online (Sandbox Code Playgroud)

在这种情况下,匹配也是三次而不是两次。但使用

curl -s -XGET localhost:9200/index/_mapping?pretty | grep '"type"'
Run Code Online (Sandbox Code Playgroud)

不会削减它。我们必须跳过以“type”关键字作为子字符串以及完全匹配的字段。在这种情况下,我们可以添加一个额外的过滤器,如下所示:

curl -s -XGET localhost:9200/index/_mapping?pretty |\
grep '"type"' | grep -v "{"
Run Code Online (Sandbox Code Playgroud)

除了上述 2 个场景之外,如果您以编程方式使用 api 将用于跟踪的数字推送到 AWS cloudwatch 或 Graphite 等,您可以使用以下代码来调用 API - 获取数据,并递归搜索关键字“type” - 同时跳过任何模糊匹配并更深入地解析具有确切名称“type”的字段。

import sys
import json
import requests

# The following find function is a minor edit of the function posted here
# /sf/ask/686534411/

def find(key, value):
  for k, v in value.iteritems():
    if k == key and not isinstance(v, dict) and not isinstance(v, list):
      yield v
    elif isinstance(v, dict):
      for result in find(key, v):
        yield result
    elif isinstance(v, list):
      for d in v:
        for result in find(key, d):
          yield result

def get_index_type_count(es_host):
  try:
    response = requests.get('https://%s/_mapping/' % es_host)
  except Exception as ex:
    print('Failed to get response - %s' % ex)
    sys.exit(1)

  indices_mapping_data = response.json()
  output = {}

  for index, mapping_data in indices_mapping_data.iteritems():
    output[index] = len(list(find('type', mapping_data)))

  return output

if __name__ == '__main__':
  print json.dumps(get_index_type_count(sys.argv[1]), indent=2)
Run Code Online (Sandbox Code Playgroud)

上面的代码也作为要点发布在这里 - https://gist.github.com/saurabh-hirani/e8cbc96844307a41ff4bc8aa8ebd7459