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