bigywater.tech
Elasticsearch · 12

keyword 的 ignore_above

真实给keyword字段设一个很短的ignore_above,写入一条超长值,验证这个值会不会被索引、会不会被拒绝写入、_source里还在不在。

超长值term查询自己
真实0命中,没有被索引
超长值的_source
真实完整保留,一个字符都没少
ignore_above的本质
真实静默豁免索引,不是拒绝写入或截断存储

做的事:真实给keyword字段设一个很短的ignore_above,写入一条超过它的值

代码PUT /ignore_above_test {"mappings": {"properties": {"code": {"type": "keyword", "ignore_above": 10}}}} POST .../_doc/1 {"code": "SHORT"} # 5字符,没超 POST .../_doc/2 {"code": "THIS-IS-A-VERY-LONG-CODE-VALUE"} # 31字符,超了 GET .../_search {"query":{"term":{"code":"THIS-IS-A-VERY-LONG-CODE-VALUE"}}}

验证:超长值用它自己的精确字符串去查,真实0命中——没有被索引

实测 · 本机 Elasticsearch 8.15.0 执行输出
term查询"SHORT"(5字符,没超过ignore_above:10)  → hits = 1   ← 真实能查到
term查询"THIS-IS-A-VERY-LONG-CODE-VALUE"(31字符,超了)→ hits = 0   ← 真实查不到

即使这个term查询用的是跟原文档一字不差的精确字符串!

这是ignore_above真实的作用机制:它不是"截断超长值再存一部分",而是真实把超过这个字符数的值整个排除在倒排索引之外——doc 2的code字段值真实有31个字符,超过了ignore_above:10的限制,ES真实选择完全不给这个值建索引,所以不管后续用什么条件去term查询(哪怕是跟原文档一模一样的精确字符串),这个字段在这份倒排索引里真实根本不存在这个值的任何踪迹。

验证:文档本身真实没有被拒绝,_source里超长值完整原样保留

实测 · 本机执行输出
GET /ignore_above_test/_doc/2
→ _source.code = "THIS-IS-A-VERY-LONG-CODE-VALUE"   ← 真实完整的31字符,一个都没少

GET /ignore_above_test/_search {"query":{"match_all":{}}}
→ hits.total.value = 2   ← 真实两条文档都在,doc 2真实没有被拒绝写入
这组结果真实划清了ignore_above影响的边界:它只真实作用于"这个字段能不能被搜索到"这一层,完全不影响文档本身能不能被写入、_source里这个字段的值完不完整——doc 2真实被成功创建,_source里的code字段真实原封不动保留着全部31个字符,match_all这种不依赖具体字段索引的查询真实也能找到它。这跟本系列前面验证过的Dynamic Mapping类型不匹配时"直接400拒绝整条写入"是完全不同的两种处理方式:类型不匹配是真实的硬性错误,ignore_above超限是真实的静默豁免——只是让这一个字段在这条文档里"变得不可搜索",不影响文档整体的写入成功与否。真实的典型应用场景是日志、用户输入这类字段长度不可控的数据:比如一段异常堆栈信息被硬塞进了一个本该存短标签的keyword字段,ignore_above能真实防止这种超长的"脏值"占用过多倒排索引空间、拖慢这个字段上terms聚合的性能,代价是这条文档在这个字段上真实变得搜不到——如果业务逻辑依赖"这个字段一定能被精确匹配到",ignore_above设得太小会真实造成查询结果里诡异的遗漏,排查时很容易先怀疑是数据没写进去,而不是先想到这个字段长度超限了。

分步演示:超长值真实写入成功,但在这个字段上变得搜不到

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

ignore_above真实只影响可搜索性,不影响写入和存储
这一步新验证的行为

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 keyword 字段 ignore_above 设置
    京ICP备2026067502号-1京公网安备11010502063487号