📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 6.8-7.4

1. 错误异常的基本描述 #

当请求中的 collapse.field 指向了不被支持的字段类型时,Elasticsearch 会报错:

unknown type for collapse field `field`; only keywords and numbers are accepted

这类错误通常在构建查询上下文时就会出现,请求会直接失败。

2. 为什么会发生这个错误 #

字段折叠不是对任意字段都可用。根据源码校验,collapse 只接受:

  • keyword 字段
  • 数值类型字段

如果字段是 textdate 之外的其他不受支持类型,或者映射经过多层封装后最终不是 KeywordFieldType / NumberFieldType,就会触发这个异常。

它和 doc_values 缺失是两个不同层次的问题:这里先失败的是“字段类型不合法”。

3. 如何排查和解决这个异常 #

  1. 检查请求里的 collapse.field 是哪个字段。
  2. _mapping 查看该字段的真实类型。
  3. 确认是否误用了 text 主字段,而不是对应的 keyword 子字段。

例如下面这种请求很容易出错:

"collapse": {
  "field": "title"
}

如果 titletext 类型,通常应改为:

"collapse": {
  "field": "title.keyword"
}

4. 如何解决这个错误 #

方案一:切换到 keyword 或数值字段 #

优先使用天然适合折叠的字段,例如:

  • 用户 ID
  • 商品 ID
  • 订单号
  • 分类编码

方案二:补充多字段映射 #

如果当前字段是 text,但业务又需要折叠,可在 mapping 中增加 keyword 子字段,然后重建索引。

示例:

"title": {
  "type": "text",
  "fields": {
    "keyword": {
      "type": "keyword"
    }
  }
}

方案三:改用聚合或应用层去重 #

如果字段本身不适合折叠,也可以考虑不用 collapse,改用聚合或应用层归并实现近似效果。

5. 预防建议 #

  • 在 DSL 生成层对 collapse.field 做白名单限制,只允许已验证字段进入。
  • 不要把全文检索字段直接复用于排序、聚合和折叠。
  • 上线前用真实 mapping 做查询回归,避免模板参数替换后指向错误字段。

6. 小结 #

unknown type for collapse field 的本质是字段类型不满足折叠要求。修复的关键不是重试,而是确保 collapse 只使用 keyword 或数值类型字段;如果当前字段不合适,就切换字段或重建 mapping。

相关错误 #

附:日志上下文 #

if (fieldType == null) {
    throw new SearchContextException(context; "no mapping found for `" + field + "` in order to collapse on");
}
if (fieldType instanceof KeywordFieldMapper.KeywordFieldType == false &&
    fieldType instanceof NumberFieldMapper.NumberFieldType == false) {
    throw new SearchContextException(context; "unknown type for collapse field `" + field +
        "`; only keywords and numbers are accepted");
}
if (fieldType.hasDocValues() == false) {
    throw new SearchContextException(context; "cannot collapse on field `" + field + "` without `doc_values`");