1、背景

我有一堆学生数据,其中湖北省的学生须要排在所有数据的最后面。其余省正序排序,对于同一个省的数据,依照年龄倒序排序。

2、剖析

对于上方的排序需要湖北省的学生数据须要排在前端,然而湖北省并不是一个字段,那么这个时候改如何实现呢?对于这种场景咱们很容易就想到须要脚本script sort来实现。

3、构建数据

3.1 mapping

PUT /index_person{  "settings": {    "number_of_shards": 1  },  "mappings": {    "properties": {      "id":{        "type": "long"      },      "name": {        "type": "keyword"      },      "age": {        "type": "integer"      },      "province":{        "type": "keyword"      }    }  }}

3.2 插入数据

PUT /index_person/_bulk{"index":{"_id":1}}{"id":1, "name":"张三","age":18,"province":"湖北"}{"index":{"_id":2}}{"id":2, "name":"李四","age":19,"province":"湖北"}{"index":{"_id":3}}{"id":3, "name":"王武","age":20,"province":"西安"}{"index":{"_id":4}}{"id":4, "name":"赵六","age":21,"province":"西安"}{"index":{"_id":5}}{"id":5, "name":"钱七","age":22,"province":"上海"}

4、实现

4.1 依据省升序排序

4.1.1 dsl

GET index_person/_search{  "query": {    "match_all": {}  },  "sort": [    {      "province": {        "order": "asc"      }    }  ]}

4.1.2 运行后果


能够看到省升序的排序程序为 上海、湖北、西安

4.2 湖北省排第一

4.2.1 dsl

GET index_person/_search{  "query": {    "match_all": {}  },  "sort": [    {      "_script": {        "type": "number",        "order": "desc",        "script": {          "lang": "painless",          "source": """                      if(params['_source']['province'] == '湖北'){                        1                      } else {                        0                      }                    """        }      }    }  ]}

4.2.2 运行后果


通过如上的 script sort排序之后,就能够看到 湖北省曾经是排到第一位了。

4.3 湖北省排第一,其余省升序排序,依照年龄倒序

4.3.1 dsl

GET index_person/_search{  "query": {    "match_all": {}  },  "sort": [    {      "_script": {        "type": "number",        "order": "desc",        "script": {          "lang": "painless",          "source": """                      if(params['_source']['province'] == '湖北'){                        1                      } else {                        0                      }                    """        }      }    },    {      "province": {        "order": "asc"      },      "age": {        "order": "desc",        "missing": "_last"      }    }  ]}

4.3.2 java代码

@Test@DisplayName("脚本排序,固定的某个值的数据排在后面,其余的数据依照别的字段排序")public void test01() throws IOException {    SearchRequest request = SearchRequest.of(searchRequest ->            searchRequest.index("index_person")                    .query(query -> query.matchAll(matchAll -> matchAll))                    .size(100)                    .sort(sort ->                            sort.script(sortScript ->                                    sortScript.type(ScriptSortType.Number)                                            .order(SortOrder.Desc)                                            .script(script ->                                                    script.inline(inline ->                                                            inline.source("if(params['_source']['province'] == params.province){\n" +                                                                            "                        1\n" +                                                                            "                      } else {\n" +                                                                            "                        0\n" +                                                                            "                      }")                                                                    .params("province", JsonData.of("湖北"))                                                    )                                            )                            )                    )                    .sort(sort ->                            sort.field(field ->                                    field.field("province").order(SortOrder.Asc)                            )                    )                    .sort(sort ->                            sort.field(field ->                                    field.field("age").order(SortOrder.Desc).missing("_last")                            )                    )    );    System.out.println("request: " + request);    SearchResponse<Object> response = client.search(request, Object.class);    System.out.println("response: " + response);}

4.3.3 运行后果

5、残缺代码

1、https://gitee.com/huan1993/spring-cloud-parent/blob/master/es/es8-api/src/main/java/com/huan/es8/script/ScriptFieldSort.java

6、参考文档

1、https://www.elastic.co/guide/en/elasticsearch/reference/7.17/sort-search-results.html