如何查看 Elasticsearch 索引有多少个字段
用 _mapping 查看映射,区分顶层属性数量与 total_fields 限额计数。提供递归统计常见字段、multi-fields、别名和 runtime 的示例,并说明字段爆炸治理。
一句话回答:执行 GET /索引名/_mapping 获取索引映射,mappings.properties 只包含普通映射的顶层入口。jq '.[].mappings.properties | length' 只数顶层属性;要估计 total_fields 限额用量,还需计入对象、多字段、别名及 runtime,见下方递归示例。
基础查询
curl -X GET "localhost:9200/your_index/_mapping?pretty"
返回结构:
{
"your_index": {
"mappings": {
"properties": {
"field1": { "type": "text" },
"field2": { "type": "keyword" }
}
}
}
}
properties 的键数量就是顶层字段数。
用 jq 一键统计
# 顶层字段数
curl -s "localhost:9200/your_index/_mapping" | jq '.[].mappings.properties | length'
用 Python 递归统计(含嵌套字段)
properties 里可能嵌套 properties(object 类型)或 fields(multi-field,如 text 的 .keyword 子字段)。还要计入 object/nested 容器、multi-fields、字段别名与映射级 runtime 字段。下面覆盖常见映射的统计;复合 runtime 字段等高级结构需结合版本核对,不能把顶层 properties 数量当成限额用量:
import requests
response = requests.get('http://localhost:9200/your_index/_mapping', timeout=10)
response.raise_for_status()
mapping = response.json()
def count_fields(props):
total = 0
for name, conf in props.items():
total += 1
if 'properties' in conf: # 嵌套 object
total += count_fields(conf['properties'])
if 'fields' in conf: # multi-field 子字段
total += count_fields(conf['fields'])
return total
for index, details in mapping.items():
mappings = details.get('mappings', {})
ordinary = count_fields(mappings.get('properties', {}))
runtime = len(mappings.get('runtime', {}))
print(index, '普通映射条目:', ordinary, '顶层 runtime:', runtime,
'合计参考值:', ordinary + runtime)
为什么关心字段数——mapping explosion
ES 默认每个索引字段上限 1000(index.mapping.total_fields.limit)。日志类索引把动态字段(如把每个用户 ID 当成字段名)写入时容易爆炸:
- 默认情况下,新增动态映射将超限时会拒绝文档;若启用
index.mapping.total_fields.ignore_dynamic_beyond_limit,行为不同,超限字段不加入映射 - 字段过多拖慢集群状态同步、撑大内存
预防:把动态键转为稳定字段名下的值,按需求采用 flattened、dynamic: false/strict 或在不需解析的 object 上设置 enabled: false。仅映射为 keyword 不会阻止无限新字段;最多减少 text 的附加 keyword 子字段。可先限制新字段、rollover 到治理后的索引,必要时 reindex;上调限额须评估内存,已存在的普通字段映射不能直接删除。
常见问题(FAQ)
Q:统计结果比预期多很多,哪来的字段?
A:多半是动态映射自动创建的:日志/JSON 数据里出现新键就自动加字段。在递归遍历中增加完整字段路径输出,找出"肇事"的动态键,然后收紧 mapping。
Q:_mapping 和 _field_caps 有什么区别?
A:_mapping 返回索引的映射定义;_field_caps(GET /索引/_field_caps?fields=*)返回字段能力汇总,跨索引统计字段更方便,还能看出同名字段在不同索引里的类型冲突。
Q:字段上限 1000 能调大吗?
A:能(index.mapping.total_fields.limit),但不建议把它当解决方案——字段过多本质是建模问题,调上限只是拖延。先治理动态字段的来源。
核查依据
本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。