Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本)

news2024/11/13 9:28:20

Elasticsearch painless脚本

  • 1.什么是painless
  • 2.painless的特性
  • 3.使用kibana进行准备操作
    • 3.1 使用kibana创建索引和映射
    • 3.2 使用kibana添加测试数据
  • 4.使用painless执行查询操作
    • 关于脚本查询须知
    • 4.1 字段查询脚本
    • 4.1 排序查询脚本
  • 5.如何使用painless执行更新操作
    • 关于脚本查询须知
    • 5.1 字段更新脚本
    • 5.2 带参数字段更新脚本
  • 6.stored script(存储使用)
  • 6.使用Java API 更新ES
  • 7.使用SpringDataElasticsearch执行脚本

1.什么是painless

painless是ElasticStack在升级到5.0版本之后新增的脚本语言,而且针对性的优化了Elasticsearch的场景。由于支持了java的静态类型和Java的lambda表达式,对于Elasticsearch数据的操作更轻量和快速,而且painless脚本因此更加简单安全。 painless脚本分为inline script(api请求时使用)和stored script(存储使用),可类比如SQL查询语句和存储过程。

es的版本与脚本的演化过程:
在这里插入图片描述
本文仅介绍常用的es脚本操作语句可以快速入手,如果需要深入的学习,官方文档才是最好的学习资料
官方文档地址:https://www.elastic.co/guide/en/elasticsearch/painless/7.9/painless-guide.html

2.painless的特性

  • 快速性能:painless脚本的运行速度是其他脚本的数倍

  • 安全性:具有方法调用/字段粒度的细粒度allowlist。有关可用类和方法的完整列表,请参阅Painless API参考

  • 可选类型:变量和参数可以使用显式类型或动态定义类型

  • 语法:painless就继承自java8,是扩展Java语法的一个子集,以提供额外的脚本语言功能

  • 优化:专门为Elasticsearch脚本设计

3.使用kibana进行准备操作

3.1 使用kibana创建索引和映射

如果你对于kibana不是很理解,可以参考我之前的文章:使用kibana对Elasticsearch索引创建删除和文档的CRUD操作命令

建立测试索引

PUT /painless_test

在这里插入图片描述
建立mapping属性映射

#建立mapping属性映射
PUT /painless_test/_mapping
{
  "properties": {
    "author": {
      "type": "text",
      "analyzer": "ik_max_word",
      "fields": {
        "keyword": {
          "type": "keyword"
        }
      }
    },
    "age": {
      "type": "integer"
    },
    "paperCount": {
      "type": "integer"
    },
    "coreJournal": {
      "type": "keyword"
    }
  }
}

3.2 使用kibana添加测试数据

PUT /painless_test/_doc/1001
{
  "author": "阿刘慈欣",
  "paperCount": [15,20,56],
  "age": 45,
  "coreJournal": [
    "MED",
    " JCR",
    " EI",
    " SCIE"
  ]
}


PUT /painless_test/_doc/1002
{
  "author": "王晋康",
  "paperCount": [23,7,32],
   "age": 63,
  "coreJournal": [
    " EI",
    " SCIE"
  ]
}

PUT /painless_test/_doc/1003
{
 "author": "周全",
 "paperCount": [57,9,34],
  "age": 18,
  "coreJournal": [
    " JCR",
    " EI"
  ]
}

4.使用painless执行查询操作

关于脚本查询须知

_search操作的query的查询结果会输出为字段脚本(script_fields)或排序脚本(sort)中的输入。因此在脚本中的操作通过Map类型的变量doc获取值,但是_search操作不会改变document的值,就像sql中的select语句。

4.1 字段查询脚本

字段查询操作:将所有作者的作品数量数组(paperCount字段)累加后查询出来

GET painless_test/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "total_goals": {
      "script": {
        "lang": "painless",
        "inline": "int total = 0; for (int i = 0; i < doc['paperCount'].length; ++i) { total += doc['paperCount'][i]; } return total;"
      }
    }
  }
}

脚本查询结果如下:
在这里插入图片描述

4.1 排序查询脚本

自定义排序操作:通过作者的名称和年龄相加进行排序(仅作示例,不考虑有无意义)

#排序脚本执行
POST painless_test/_search
{
  "query": {
    "match_all": {}
  },
   "sort": {
    "_script": {
      "type": "string",
      "order": "desc",
      "script": {
        "lang": "painless",
        "inline": "doc['author.keyword'].value+doc['age']"
      }
    }
  }
}

在这里插入图片描述

5.如何使用painless执行更新操作

关于脚本查询须知

脚本更新操作推荐使用update_by_query的API,该API首先通过query语句(可以使用各种query语句)查询出满足条件的记录,再根据脚本中的操作更新查询出来的记录。需要注意的是,相对于查询使用doc访问文档的内容,更新使用的是ctx。

5.1 字段更新脚本

需求描述:原始文档中的coreJournal字段中值存在空格,现在要求将空格去除
实现步骤:首先根据查询条件为存在coreJournal字段的文档,然后再对coreJournal中的值进行遍历去除空格操作

POST cqu_dev_journal_paper/_update_by_query
{
  "script": {
    "source": " for (int i = 0; i < ctx._source.coreJournal.length; i++) {   
    			ctx._source.coreJournal[i]=ctx._source.coreJournal[i].trim(); }",
    "lang": "painless"
  },
  "query": {
    "bool": {
      "must": [
        {
          "exists": {
            "field": "coreJournal"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  }
}

执行效果如下:
在这里插入图片描述

5.2 带参数字段更新脚本

需求描述:原始文档中年龄在30岁以上作者字段都要以"科幻作家”开头
实现步骤:首先根据查询条件为年龄在30岁以上的文档,然后再对作者字段进行更新

POST painless_test/_update_by_query
{
  "script": {
    "source": " ctx._source.author=params.prefix+ctx._source.author",
    "lang": "painless"
    , "params": {
        "prefix":"科幻作家"
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "age": {
              "from": 30
            }
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  }
}

执行效果如下:
在这里插入图片描述

6.stored script(存储使用)

# 创建单独的脚本
POST _scripts/add-age
{
  "script": {
    "lang": "painless",
    "source": "doc['age'].value + params.myage"
  }
}

# 获取脚本
GET _scripts/add-age

# 通过指定scriptid进行调用查询
GET painless_test/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "addage": {
      "script": {
       "id": "add-age", 
        "params": {
          "myage": 15
        }
      }
    }
  }
}

# 删除脚本
DELETE _scripts/calculate-score

6.使用Java API 更新ES

通过Java API实现 5.1章节的需求

需求描述:原始文档中的coreJournal字段中值存在空格,现在要求将空格去除
实现步骤:首先根据查询条件为存在coreJournal字段的文档,然后再对coreJournal中的值进行遍历去除空格操作

  public static BulkByScrollResponse updateByQuery() {
        BulkByScrollResponse bulkResponse = null;
        try {
            UpdateByQueryRequest request = new UpdateByQueryRequest("painless_test");
            request.setConflicts("proceed");
            request.setQuery(QueryBuilders.existsQuery("coreJournal"));

            String strScript = "for (int i = 0; i < ctx._source.coreJournal.length; i++) {ctx._source.coreJournal[i]=ctx._source.coreJournal[i].trim(); }"Script script = new Script(
                    ScriptType.INLINE, "painless",
                    strScript,
                    Collections.emptyMap());
            request.setScript(script);

            bulkResponse = restHighLevelClient.updateByQuery(request, RequestOptions.DEFAULT);

        } catch (IOException e) {
            log.error("ES更新异常", e.getMessage());
        }
        return bulkResponse;
    }

7.使用SpringDataElasticsearch执行脚本

通过SpringDataElaticsearch实现 5.1章节的需求

需求描述:原始文档中的coreJournal字段中值存在空格,现在要求将空格去除
实现步骤:首先根据查询条件为存在coreJournal字段的文档,然后再对coreJournal中的值进行遍历去除空格操作

 public AjaxResult updateESScript() {
        
        int updatedCount = 0;
        try {
            //构建布尔查询语句,存在coreJournal字段的值
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.must(QueryBuilders.existsQuery("coreJournal"));

            NativeSearchQuery query = new NativeSearchQueryBuilder()
                    .withQuery(boolQueryBuilder)
                    .build();

            //构建查询更新语句
            UpdateQuery updateQuery = UpdateQuery.builder(query)
                    .withScriptType(ScriptType.INLINE)
                    .withScript("for (int i = 0; i < ctx._source.coreJournal.length; i++) {ctx._source.coreJournal[i]=ctx._source.coreJournal[i].trim(); }")
                    .withLang("painless")
                    .withAbortOnVersionConflict(false)
                    .build();

            /**
             * 使用ElasticsearchOperations.updateByQuery()方法执行脚本更新
             *  param: updateQuery 要执行的查询更新语句
             *  param: IndexCoordinates.of("painless_test") 获取要执行的索引
             */
            ByQueryResponse byQueryResponse = elasticsearchOperations.updateByQuery
                    (updateQuery, IndexCoordinates.of("painless_test"));

            long updated = byQueryResponse.getUpdated();
            System.out.println("本次共更新es文档数量:" + updated);

        } catch (Exception e) {
            log.info("==============es更新报错===========");
            e.printStackTrace();
            return AjaxResultGenerator.error(e.getMessage());
        }
        return AjaxResultGenerator.success(updatedCount);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/448354.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Security 04 自定义认证

登录⽤户数据获取 SecurityContextHolder Spring Security 会将登录⽤户数据保存在 Session 中。但是&#xff0c;为了使⽤⽅便, Spring Security 在此基础上还做了⼀些改进&#xff0c;其中最主要的⼀个变化就是线程绑定。当⽤户登录成功后,Spring Security 会将登录成功的⽤户…

Node内置模块 【crypto加密模块】

文章目录 &#x1f31f;前言&#x1f31f;crypto加密模块&#x1f31f;Crypto模块介绍&#x1f31f;Hash算法&#x1f31f;Hash算法介绍&#x1f31f;Hash算法之MD5&#x1f31f;算法简介&#x1f31f;MD5加密使用 &#x1f31f;Hash算法之SHA1&#x1f31f;算法简介&#x1f3…

二叉树经典题题解

目录 &#x1f345;1.单值二叉树&#x1f345; &#x1f349; 2.相同的树&#x1f349; &#x1f34a;3.对称二叉树&#x1f34a; &#x1f34e;4.另一颗树的子树&#x1f34e; &#x1f34f;5.翻转二叉树&#x1f34f; &#x1f351;6.平衡二叉树&#x1f351; &#x1f3…

【LeetCode: 1027. 最长等差数列 | 暴力递归=>记忆化搜索=>动态规划】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

SHELL的脚本编辑与运行

目录 1.编写脚本for1.sh,使用for循环创建20账户&#xff0c;账户名前缀由用户从键盘输入&#xff0c;账户初始密码由用户输入&#xff0c;例如&#xff1a;test1、test2、test3、、test10 a.编辑脚本 b.运行脚本 c.进行检验 2.编写脚本for2.sh,使用for循环&#xff0c;通过…

如何把aac转化为mp3,4个处理方法教给你

一般情况下&#xff0c;将 AAC 文件转换为 MP3 文件有以下几种情况&#xff1a;设备不兼容&#xff1a;AAC 格式通常用于苹果设备上。如果您想在其他设备上播放音频文件&#xff0c;如 Android 手机、MP3 播放器等&#xff0c;就需要将其转换为 MP3 格式。需要更好的兼容性&…

机器学习(七):基于多项式贝叶斯对蘑菇毒性分类预测分析

系列文章目录 作者&#xff1a;i阿极 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏&#x1f4c1;评论&#x1f4d2;关注…

第六章 原型模式

文章目录 前言一、克隆羊问题sheep类clint 调用方 二、引入原型模式动态克隆对象sheep类clint 类 三、原型模式在Spring框架中源码分析四、深拷贝与浅拷贝完整代码DeepCloneableTargetDeepProtoTypeClient2 五、原型模式的注意事项和细节 前言 一、克隆羊问题 sheep类 package…

mysql查询字段未加引号问题及隐式转换

1. 问题重现 最近线上出了个问题&#xff0c;用户明明没有投票&#xff0c;却提示已投票&#xff0c;我查询数据&#xff0c;刚开始没有查出数据&#xff0c;后来却查出数据了&#xff0c;以为没有问题&#xff0c;后来以为是插入的时候通过int类型插入&#xff0c;导致varcha…

美国最大公共养老基金之一Strs Ohio不断增持IonQ股票

​ &#xff08;图片来源&#xff1a;网络&#xff09; 截至2022年12月31日第四季度末&#xff0c;美国最大的公共养老基金之一Strs Ohio发布报告称&#xff0c;其一直在增持IonQ&#xff0c;Inc.&#xff08;纽约证券交易所代码&#xff1a;IONQ&#xff09;的股份。资产管理公…

如何在云服务器/云主机上部署最新版本的Hadoop3.3.5(Ubuntu20.0.4)

在云服务器上部署Hadoop 步骤1&#xff1a;更新系统 sudo apt-get update sudo apt-get upgrade步骤2&#xff1a;安装Java Hadoop需要Java运行环境。首先&#xff0c;安装OpenJDK 8&#xff1a; sudo apt-get install openjdk-8-jdk检查Java版本&#xff1a; java -versi…

上海车展:比亚迪宋L概念车全球首发,这是要硬扛特斯拉?

纵观2023年的新能源汽车市场&#xff0c;特斯拉可以说当仁不让地成为了全球最为“吸睛”的车企之一。凭借一系列令无数人瞠目结舌的降价举措&#xff0c;特斯拉给全球汽车市场带来了强烈冲击。虽然特斯拉上海工厂已经接近满负荷运转&#xff0c;但是面对雪片般飞来的订单依然供…

SpringBoot设置动态定时任务

SpringBoot设置动态定时任务 1.准备工作 搭建SpringBoot工程 引入相关依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><depende…

ROS学习第八节——话题通信自定义msg

1.介绍 在 ROS 通信协议中&#xff0c;数据载体是一个较为重要组成部分&#xff0c;ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty.... 但是&#xff0c;这些数据一般只包含一个 data 字段&#xff0c;结构的单一意味着功能上的…

Java基础(九)多线程

我们之前学习的程序在没有跳转语句的情况下&#xff0c;都是由上至下沿着一条路径依次执行。现在想要设计一个程序&#xff0c;可以同时有多条执行路径同时执行。比如&#xff0c;一边游戏&#xff0c;一边qq聊天&#xff0c;一边听歌&#xff0c;怎么设计&#xff1f; 要解决…

每日一个小技巧:今天告诉你拍照识别文字的软件有哪些

在现代社会里&#xff0c;手机已经成为了人们生活中必不可少的工具。它的功能众多&#xff0c;比如通讯、上网、拍照以及导航等&#xff0c;为我们的生活带来了许多便利。除此之外&#xff0c;手机还能帮助我们解决一些实际的问题&#xff0c;例如&#xff0c;当你需要识别图片…

Spring Aop详解汇总

文章目录 近期想法什么是AOPSpringAOP与AspectjSpringAOP体系概述概念详解连接点- Jointpoint切入点- Pointcut通知- Advice切面- Aspect织入- Weaving 实现原理—动态代理JDK动态代理描述原理代码示例注意执行结果 优点缺点 CGLib动态代理描述原理代码示例注意执行结果 优点缺…

ChatGPT会凉吗?巴菲特、马斯克呼吁暂停

ChatGPT 迅速“风靡”全球&#xff0c;无疑成为了人工智能领域备受瞩目的“明星产品”&#xff0c;然而随着 ChatGPT 应用越来越广泛&#xff0c;陆续爆出被用于学术造假、制作黑客武器以及泄露用户敏感聊天信息等一系列负面新闻。至此&#xff0c;社会开始重新审视类似 ChatGP…

图像傅里叶变换以及频谱中心化

图像的空域滤波&#xff1a; I ∗ G I*G I∗G 矩阵 I I I与一个小矩阵 G G G进行卷积 图像的频域滤波&#xff1a; F − 1 [ F [ I ] H ] F^{-1}[F[I]\times H] F−1[F[I]H] 矩阵 I I I的傅里叶变换与同样大小的矩阵 H H H进行对应元素相乘&#xff0c;然后将结果通过逆傅里…

并查集解决图的连通性问题

并查集 1. 定义2.并查集3.模板代码4. 力扣例题4.1 剑指 Offer II 118. 多余的边4.2 力扣695. 岛屿的最大面积 1. 定义 在计算机科学中&#xff0c;并查集&#xff08;英文&#xff1a;Disjoint-set data structure&#xff0c;直译为不交集数据结构&#xff09;是一种数据结构&…