如何查看 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),但不建议把它当解决方案——字段过多本质是建模问题,调上限只是拖延。先治理动态字段的来源。

核查依据

本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。


延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台