目錄
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、完整程式碼
6、參考文件
1、https://www.elastic.co/guide/en/elasticsearch/reference/7.17/sort-search-results.html