最適化の目的で、合計フィールド数を削減しようとしています。ただし、その前に、実際にフィールドがいくつあるかを把握したいと思います。 _stats
エンドポイントに情報がないようで、移行ツールがフィールド数の計算をどのように行うのかよくわかりません。
エンドポイントを使用するか、他の方法で、指定されたインデックスの合計フィールド数を取得する方法はありますか?
他の回答が提供したものをさらに構築するために、マッピングを取得してから、キーワードtype
が出力に表示される回数を数えるだけで、各フィールドにはタイプが必要なため、フィールドの数がわかります。 :
curl -s -XGET localhost:9200/index/_mapping?pretty | grep type | wc -l
ヴァルによる最初の答えは私にとっても問題を解決します。しかし、誤解を招くような数字につながる可能性のあるいくつかのコーナーケースをリストアップしたかっただけです。
例えば
"content_type" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
}
}
},
これはgrep type
に3回一致しますが、2回だけ一致する必要があります。つまり、「content_type」とは一致しないはずです。このシナリオは簡単に修正できます。
の代わりに
curl -s -XGET localhost:9200/index/_mapping?pretty | grep type
使用する
curl -s -XGET localhost:9200/index/_mapping?pretty | grep '"type"'
'"type"'の完全一致を取得するには
例えば
"type" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
}
}
},
この場合も、試合は2回ではなく3回です。しかし、
curl -s -XGET localhost:9200/index/_mapping?pretty | grep '"type"'
それをカットするつもりはありません。完全一致だけでなく、部分文字列として「type」キーワードを含むフィールドをスキップする必要があります。この場合、次のようにフィルターを追加できます。
curl -s -XGET localhost:9200/index/_mapping?pretty |\
grep '"type"' | grep -v "{"
上記の2つのシナリオに加えて、APIをプログラムで使用して追跡用の番号をプッシュする場合、つまりAWSクラウドウォッチや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
あなたはこれを試すことができます:
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
その情報は、インデックスAPIの_mapping
エンドポイントで取得できます。 https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-mapping.htmlを参照してください。
Get Mapping APIを使用すると、インデックスまたはインデックス/タイプのマッピング定義を取得できます。
GET/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