美文网首页js css html
elasticsearch实现简单的脚本排序(script so

elasticsearch实现简单的脚本排序(script so

作者: huan1993 | 来源:发表于2023-01-12 20:31 被阅读0次

    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

    相关文章

      网友评论

        本文标题:elasticsearch实现简单的脚本排序(script so

        本文链接:https://www.haomeiwen.com/subject/zacicdtx.html