暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ElasticSearch排序引发的异常及解决

大数据记事本 2020-05-14
4026

背景:项目中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,在查询时也不会出现异常。

          文章转载自大数据记事本,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论