背景:项目中ES查询相关的方法用到了根据给定字段进行排序,之前的开发测试中运行正常,没有出现什么问题。今天在根据一个字段排序时,出现了异常。现对问题及解决方法进行简单总结。
ElasticSearch版本:7.5.1
异常信息:
Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]

通过查找资料,发现是在sort的时候排序字段是一个未定义mapping的字段(实际是因为字段名的大小写未对应,导致给定的排序字段并未在索引中定义mapping),
代码如下所示,这里排序是调用了SearchSourceBuilder对象的sort方法,参数直接是排序字段名和SortOrder.ASC
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();if (pageNo <= 1) {pageNo = 1;}searchSourceBuilder.query(queryBuilder).from((pageNo - 1) * pagesize).size(pagesize).sort(sortField,SortOrder.ASC).fetchSource(include, new String[]{});
这样在查询时,如果排序字段没有定义mapping,就出现了上面的异常。
继续查找相关资料,发现在搜索中添加排序条件时,可以用unmapped_type关键字,来对未指定mapping的排序字段指定mapping类型:
{"sort" : [{ "price" : {"unmapped_type" : "long"} },],"query" : {"term" : { "user" : "diao" }}}
那么如何通过Java High Level REST Client来定义呢?
查看SearchSourceBuilder的sort方法,发现参数除了指定排序字段,还可以传入一个SortBuilder对象

SortBuilder是一个抽象类,有4个实现类,分别是:
FieldSortBuilder:根据某个字段排序
GeoDistanceSortBuilder:根据地理位置排序
ScriptSortBuilder:根据自定义脚本排序
ScoreSortBuilder:根据score评分排序
这里我们是根据字段排序,所以传一个FiledSortBuilder对象即可
①可以通过new的方式构建FiledSortBuilder对象,参数为排序字段
②可以通过SortBuilders类的静态方法fieldSort构建FiledSortBuilder对象(实质是在方法中new了该对象),该类也提供了构建各种排序对象的方法。
然后可以调用SortBuilder实例对象的sort方法设定升降序和调用unmappedType方法给未定义mapping的字段一个默认的类型
searchSourceBuilder.query(queryBuilder).from((pageNo - 1) * pagesize).size(pagesize).sort(SortBuilders.fieldSort(sortField).order(SortOrder.ASC).unmappedType("keyword")).fetchSource(include, new String[]{});
这样修改以后,即使排序的字段没有定义mapping,在查询时也不会出现异常。




