使用Elasticsearch Java Client时collapse的inner_hits解析失败问题排查
问题:Elasticsearch Java Client构建带inner_hits的collapse查询报错
错误信息
Caused by: co.elastic.clients.elasticsearch._types.ElasticsearchException: [es/search] failed: [x_content_parse_exception] [1:500] [collapse] failed to parse field [inner_hits]
代码实现
FieldCollapse构建代码
FieldCollapse.Builder builder = new FieldCollapse.Builder() // .field(collapse.getField()); if (collapse.getInnerHits() != null) { List<InnerHits> innerHits = getInnerHitsBuilderList(collapse.getInnerHits()); builder.innerHits(innerHits); } return Optional.of(builder.build());
InnerHits构建代码
InnerHits.Builder builder = new InnerHits.Builder().name(innerHit.getName()); NullOrEmpty.optional(innerHit.getFetchFields()) .ifPresent(p -> builder.fields(Lists.mutable.ofAll(p))); NullOrEmpty.optional(innerHit.getStoredFields()) .ifPresent(p -> builder.storedField(Lists.mutable.ofAll(p)));
生成的查询结构(collapse部分)
"collapse": { "field": "fielda.innerFieldb", "inner_hits": [ { "name": "Topics", "size": 100, "collapse": { "field": "topic.topicId" }, "fields": [ "topic.shortName" ], "stored_field": [ "topic.shortName" ] } ] }
官方文档示例格式
Elasticsearch官方语法中,inner_hits是单个对象而非数组:
"collapse": { "field": "user.id", "inner_hits": { "name": "most_recent", "size": 5, "sort": [ { "@timestamp": "desc" } ] }, "max_concurrent_group_searches": 4 }
注意:Java Client的FieldCollapse类中inner_hits被定义为List<InnerHits>类型,但服务端不接受数组格式,这是问题核心。
问题原因与解决方法
原因
Elasticsearch服务端的collapse语法仅支持单个inner_hits对象,但Java Client的FieldCollapse.Builder提供了接收列表的方法,导致生成的JSON中inner_hits是数组,与服务端要求的格式不匹配,触发解析错误。
解决方法
直接传入单个InnerHits实例,而非列表。修改后的FieldCollapse构建代码如下:
FieldCollapse.Builder builder = new FieldCollapse.Builder() // .field(collapse.getField()); if (collapse.getInnerHits() != null) { List<InnerHits> innerHitsList = getInnerHitsBuilderList(collapse.getInnerHits()); if (!innerHitsList.isEmpty()) { builder.innerHits(innerHitsList.get(0)); // 传入单个InnerHits对象 } } return Optional.of(builder.build());
修正后的查询结构
生成的collapse部分会符合服务端要求的对象格式:
"collapse": { "field": "fielda.innerFieldb", "inner_hits": { "name": "Topics", "size": 100, "collapse": { "field": "topic.topicId" }, "fields": [ "topic.shortName" ], "stored_field": [ "topic.shortName" ] } }
内容的提问来源于stack exchange,提问作者John B
相关产品推荐
相关产品推荐

