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

目录
  • 1、背景
  • 2、分析
  • 3、构建数据
    • 3.1 mapping
    • 3.2 插入数据
  • 4、实现
    • 4.1 根据省升序排序
    • 4.2 湖北省排第一
    • 4.3 湖北省排第一,其余省升序排序,按照年龄倒序
  • 5、完整代码

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、完整代码

代码地址

到此这篇关于详解Elasticsearch如何实现简单的脚本排序的文章就介绍到这了,更多相关Elasticsearch脚本排序内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java详解ScriptEngine接口动态执行JS脚本

    目录 简介 Eval(String script) 描述 实例代码 Put() and Get() 描述 实例代码 CompiledScript 描述 实例代码 Bindings 描述 实例代码 大多的方法描述都来自于jdk11API帮助文档,由于是机翻,可能有些难以理解,大家多多担待 简介 首先来看一下JDK11API文档中对ScriptEngine的描述 模块 java.scripting 软件包 javax.script Interface ScriptEngin public inter

  • 详解elasticsearch实现基于拼音搜索

    目录 1.背景 2.安装拼音分词器 3.拼音分词器提供的功能 4.简单测试一下拼音分词器 4.1 dsl 4.2 运行结果 5.es中分词器的组成 6.自定义一个分词器实现拼音和中文的搜索 1.创建mapping 2.插入数据 3.搜索数据 1.背景 一般情况下,有些搜索需求是需要根据拼音和中文来搜索的,那么在elasticsearch中是如何来实现基于拼音来搜索的呢?可以通过elasticsearch-analysis-pinyin分析器来实现. 2.安装拼音分词器 # 进入 es 的插件目录

  • 详解log4j.properties的简单配置和使用

    本文介绍了详解log4j.properties的简单配置和使用,分享给大家,具体如下: 简单log4j.properties配置示例 ### set log levels ### log4j.rootLogger = INFO , console , debug , error ### console ### log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = Syst

  • 详解Navicat Premium 15 无限试用脚本的方法

    具体内容如下所示: @echo off echo\ echo\ echo 适用于 Navicat 12.0.29 echo 正在清除试用信息... for /f %%i in ('reg query HKCU\Software\Classes\CLSID') do call:checkDelCLSID %%i reg delete HKCR\NavicatProfileBackup /f 1>nul 2>nul reg delete HKCR\NavicatProfileBatchJob /f

  • 详解mysql查询缓存简单使用

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一. 当我们开启Mysql的查询缓存,当执行完全相同的SQL语句的时候,服务器就会直接从缓存中读取结果.当数据被修改, 之前的缓存会失效,所以修改比较频繁的表不适合做查询缓存. 一.查询

  • Spring data jpa的使用与详解(复杂动态查询及分页,排序)

    一. 使用Specification实现复杂查询 (1) 什么是Specification Specification是springDateJpa中的一个接口,他是用于当jpa的一些基本CRUD操作的扩展,可以把他理解成一个spring jpa的复杂查询接口.其次我们需要了解Criteria 查询,这是是一种类型安全和更面向对象的查询.而Spring Data JPA支持JPA2.0的Criteria查询,相应的接口是JpaSpecificationExecutor. 而JpaSpecifica

  • 详解JavaScript如何实现四种常用排序

    目录 一.插入排序 直接插入排序 二.交换排序 (1)冒泡排序 (2)快速排序 三.选择排序 (1)简单选择排序 (2)堆排序 四.归并排序 一.插入排序 插入排序有直接插入排序,折半插入排序,希尔排序,这里只实现常用的直接插入排序 直接插入排序 将左侧序列看成一个有序序列,每次将一个数字插入该有序序列. 插入时,从有序序列最右侧开始比较,若比较的数较大,后移一位. function insertSort(array) { //第一个默认已经排好 for (let i = 1; i < arra

  • 详解小程序之简单登录注册表单验证

    这段时间在做员工管理的小程序,前期在登录注册上花了不少功夫,今天就给大家分享下. 效果图,wxss的内容较简单,自己编写即可. ##主要内容 一.首先我是在util.js中引入表单正则验证规则,给予login.js来引用 function regexConfig() { var reg = { userid: /^[A-Za-z0-9]+$/, //邮箱正则验证 phone: /^1(3|4|5|7|8)\d{9}$/, //手机号正则验证 cards: /^[\u4e00-\u9fa5]{2,

  • 详解JAVA使用Comparator接口实现自定义排序

    1.原则 Comparator接口可以实现自定义排序,实现Comparator接口时,要重写compare方法: int compare(Object o1, Object o2) 返回一个基本类型的整型 如果要按照升序排序,则o1 小于o2,返回-1(负数),相等返回0,01大于02返回1(正数) 如果要按照降序排序,则o1 小于o2,返回1(正数),相等返回0,01大于02返回-1(负数) import java.util.ArrayList; import java.util.Compar

  • 详解Selenium+PhantomJS+python简单实现爬虫的功能

    Selenium 一.简介 selenium是一个用于Web应用自动化程序测试的工具,测试直接运行在浏览器中,就像真正的用户在操作一样 selenium2支持通过驱动真实浏览器(FirfoxDriver,IternetExplorerDriver,OperaDriver,ChromeDriver) selenium2支持通过驱动无界面浏览器(HtmlUnit,PhantomJs) 二.安装 Windows 第一种方法是:下载源码安装,下载地址(https://pypi.python.org/py

随机推荐