有时候想看看es中某个索引中所有的字段,直接通过查询mapping是很难看出所有的字段的,里面包含的属性太多了。本博文将实现获取mapping中所有字段的算法。
示例new_user2索引中的mapping值:
{
"new_user2": {
"mappings": {
"properties": {
"address": {
"properties": {
"city": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"province": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"age": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
示例代码:【直接在mapping中获取】
import json
with open('text.txt', 'r', encoding='utf-8') as f:
data = f.read()
json_data = json.loads(data)
# print(json_data)
for key, value in json_data.items():
index = key
mappings = value
def func(dic):
res = []
def traceback(mapping, fields_join):
if not isinstance(mapping, dict):
return res.append(fields_join)
for key, value in mapping.items():
if fields_join:
traceback(value, fields_join + '.' + key)
else:
traceback(value, key)
def filter_fields(fields: list):
fields_lst = []
for field in fields:
field = field.replace('mappings.properties.', '').replace('.properties', '')
# 注意:下面几个判断最好替换字符串长的在前面,防止出错
if field[-28:] == '.fields.keyword.ignore_above':
field = field[:-28]
elif field[-20:] == '.fields.keyword.type':
field = field[:-20]
elif field[-15:] == '.fields.keyword':
field = field[:-15]
elif field[-5:] == '.type':
field = field[:-5]
fields_lst.append(field)
return list(set(fields_lst))
traceback(dic, '')
return filter_fields(res)
ret = func(mappings)
print("index: ", index)
print("fields: ", ret)
运行结果:
注意:也可以直接通过查询语句,直接在es中查询,通过响应的数据中获取:res['hits']['hits']。但是,由于查询出的数据未必所有字段都是有数据的,所有这种方法不是准确的。最好还是直接从获取到的_mapping中直接获取!