详解Elasticsearch如何实现简单的脚本排序

作者:huan1993 时间:2022-03-13 13:17:50 

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 运行结果

详解Elasticsearch如何实现简单的脚本排序

可以看到省升序的排序顺序为 上海、湖北、西安。

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 运行结果

详解Elasticsearch如何实现简单的脚本排序

通过如上的 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 运行结果

详解Elasticsearch如何实现简单的脚本排序

5、完整代码

代码地址

来源:https://www.cnblogs.com/huan1993/p/17047871.html

标签:Elasticsearch,脚本,排序
0
投稿

猜你喜欢

  • 8种常见的Java不规范代码

    2023-05-24 10:59:53
  • 花样使用Handler与源码分析

    2023-07-30 08:36:31
  • Java多种经典排序算法(含动态图)

    2023-09-24 00:45:02
  • spring webflux自定义netty 参数解析

    2023-07-26 18:38:25
  • 浅谈Java日志框架slf4j作用及其实现原理

    2022-11-02 19:02:04
  • 详解java中的static关键字

    2023-09-24 01:44:12
  • 带你了解如何使用Spring基于ProxyFactoryBean创建AOP代理

    2022-04-28 09:17:37
  • Java中Future和FutureTask的示例详解及使用

    2023-01-29 11:48:42
  • 基于jdk动态代理和cglib动态代理实现及区别说明

    2022-04-11 00:32:44
  • SpringBoot分页查询功能的实现方法

    2023-07-14 02:22:21
  • C#对文件进行加密解密代码

    2023-03-22 12:17:18
  • springcloud之自定义简易消费服务组件

    2022-01-29 00:18:24
  • Java struts2捕获404错误的方法汇总

    2021-10-14 00:12:16
  • Java最简洁数据结构之冒泡排序快速理解

    2023-12-01 06:31:52
  • Java基于接口实现模拟动物声音代码实例

    2022-07-28 04:46:07
  • JAVA语言编程格式高级规范

    2021-08-21 01:43:54
  • C# 格式化JSON的两种实现方式

    2023-03-14 05:31:16
  • Java经典面试题最全汇总208道(五)

    2023-11-10 07:06:46
  • Spring实现默认标签解析流程

    2021-07-29 10:07:55
  • C#学习笔记整理_浅谈Math类的方法

    2022-04-11 06:16:48
  • asp之家 软件编程 m.aspxhome.com