出于优化目的,我正在尝试减少我的总字段数。然而,在我这样做之前,我想了解一下我实际拥有多少个字段。
_stats
端点中似乎没有任何信息,我不太清楚迁移工具如何进行字段计数计算。
是否有某种方式,无论是通过端点还是其他方式,来获取指定索引的总字段数?
要进一步构建其他答案提供的内容,您可以获得映射,然后简单地计算关键字
type
出现在输出中的次数,这给出了字段数,因为每个字段都需要一个类型:
curl -s -XGET localhost:9200/index/_mapping?pretty | grep type | wc -l
你可以试试这个:
curl -s -XGET "http://localhost:9200/index/_field_caps?fields=*" | jq '.fields|length'
无需编写脚本即可在 Kibana 中获得相对估计的快速方法(我不相信这是 100% 精确的,但这是判断您的动态字段是否由于某种原因爆炸到巨大数字的简单方法).
在 Kibana 开发工具中运行此查询
GET /index_name/_mapping
在 Kibana 输出中,对 "type"
(包括引号)的所有实例执行
search。这将计算实例并为您提供答案。 (在这个例子中,804)
如果你摸不着头脑为什么会出现
[remote_transport_exception]
错误,这可能会有所帮助
Limit of total fields [1000] in index [index_name] has been exceeded
Val 的第一个答案也为我解决了这个问题。但我只是想列出一些可能导致误导性数字的极端情况。
例如
"content_type" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
}
}
},
这将匹配
grep type
三次,而它应该只匹配两次,即它不应该匹配“content_type”。这种情况很容易解决。
代替
curl -s -XGET localhost:9200/index/_mapping?pretty | grep type
使用
curl -s -XGET localhost:9200/index/_mapping?pretty | grep '"type"'
获得“类型”的精确匹配
例如
"type" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
}
}
},
在这种情况下,比赛也是三次而不是两次。但是使用
curl -s -XGET localhost:9200/index/_mapping?pretty | grep '"type"'
不会削减它。我们将不得不跳过以“type”关键字作为子字符串以及完全匹配的字段。在这种情况下,我们可以像这样添加一个额外的过滤器:
curl -s -XGET localhost:9200/index/_mapping?pretty |\
grep '"type"' | grep -v "{"
除了上述两种情况之外,如果您以编程方式使用 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
# https://stackoverflow.com/questions/9807634/find-all-occurrences-of-a-key-in-nested-python-dictionaries-and-lists
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)
上面的代码也作为要点发布在这里 - https://gist.github.com/saurabh-hirani/e8cbc96844307a41ff4bc8aa8ebd7459
您可以使用索引 API 的
_mapping
端点获取该信息,请参阅https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-mapping.html
获取映射 API 允许检索索引或索引/类型的映射定义。
获取/twitter/_mapping/tweet
卷曲:
curl [elasticsearch adress]/[index]/_mapping?pretty
一个字段可以有多个“类型”: 例如
"datapath-id": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
}
我们可以忽略“字段”中的“类型”以获得准确的字段数。一个例子是:
import json
def myprint(d, field_count):
for k, v in d.iteritems():
if isinstance(v, dict):
if k != "fields":
field_count = myprint(v, field_count)
else:
print "{0} : {1}".format(k, v)
field_count += 1
return field_count
with open("output/mappings.json") as f:
d = json.load(f)
final_field_count = myprint(d, field_count=0)
print "field count", final_field_count
我要求 chatGPT 为 jq 创建一个过滤器。
显示不包括 metadata_field 的计数。
curl -s -XGET -u 'elastic:changeme' -k "http://localhost:9200/target_index/_field_caps?fields=*" | jq '.fields | with_entries(select(any(.value[]; .metadata_field == false))) | length'