2019 年使用 Elasticsearch 7.x 时,一个按 createDate 倒序查询的接口,在新索引上报错。给排序增加 unmapped_type 后,当时的查询恢复。
当时使用的 Java 片段
下面是旧 Java High Level REST Client 风格:
FieldSortBuilder sort = SortBuilders
.fieldSort("createDate")
.order(SortOrder.DESC)
.unmappedType("date");
searchSourceBuilder.sort(sort);
对应请求结构可以写为:
GET /example_articles/_search
{
"sort": [
{
"createDate": {
"order": "desc",
"unmapped_type": "date"
}
}
]
}
unmapped_type 指定遇到未映射字段时按什么类型处理,避免该类排序失败;它不会给索引补建字段映射。ES 7.3 排序说明
空数据不是根因的充分描述
空索引可以已经有显式 mapping;有文档的索引也可能一直没有 createDate。动态映射只在相应字段进入文档、满足配置规则时才可能建立,不能说“有第一条数据就一定创建所有字段”。
先检查真正被查询的目标:
GET /example_articles/_mapping
如果请求覆盖多个索引,也要分别检查 createDate 是否存在、是否都是 date,以及日期格式是否兼容。
三类问题不能混用一个选项
未映射字段、已映射但某条文档缺值、不同索引里类型冲突,是三种不同情况。unmapped_type 针对第一种,并不修复后两种的所有问题;缺值排序可另看 missing 选项,类型冲突则应先修正数据模型。
对于明确要求按日期排序的新索引,预先声明 mapping 更能表达契约。保留 unmapped_type 作为兼容选择时,也应知道自己在容忍什么,不能让它掩盖本应存在的字段缺失。