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

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);
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】第二节:线性回归和线性分类

作者&#x1f575;️‍♂️&#xff1a;让机器理解语言か 专栏&#x1f387;&#xff1a;机器学习sklearn 描述&#x1f3a8;&#xff1a;本专栏主要分享博主学习机器学习的笔记和一些心得体会。 寄语&#x1f493;&#xff1a;&#x1f43e;没有白走的路&#xff0c;每一步都算…

Text-to-SQL提示工程【Prompt Engineering】

我们刚刚启动了一个开源项目pg-text-query&#xff0c;目标是为文本到 SQL 制作生产就绪的大型语言模型 (LLM) 提示。 我们的目标是 利用 LLM、我们自己对 PostgreSQL 数据库的深入了解以及严格的测试来开发一流的文本到 SQL 的翻译。 推荐&#xff1a;用 NSDT设计器 快速搭建…

【MySQL】C语言连接数据库

在使用数据库的时候&#xff0c;我们是操作客户端方的&#xff0c;向服务器请求数据。MySQL的端口号-3306 连接mysql需要头文件&#xff1a;#include<mysql/mysql.h> 基础连接步骤&#xff1a; 1.创建连接句柄 MYSQL mysql_con;//连接句柄 2.初始化连接句柄mysql_i…

「OceanBase 4.1 体验」|大厂开始接入的国产分布式数据库,不来了解了解?

OceanBase 4.1 体验 前言OCP Express在线升级功能租户级物理备库TP&#xff08;事务处理&#xff09;和AP&#xff08;分析处理&#xff09;优化TP 性能优化AP 性能优化 结尾 前言 上次我们讲了本人自己亲自上手OceanBase 4.1的初体验&#xff0c;国产的分布式数据库也太太太太…

有哪些好用的AI工具?

现在有很多好用的AI工具&#xff0c;以下是一些常用的&#xff1a; 1. TensorFlow&#xff1a;谷歌开发的深度学习框架&#xff0c;支持多种编程语言&#xff0c;包括Python、C、Java等。 2. PyTorch&#xff1a;Facebook开发的深度学习框架&#xff0c;易于使用&#xff0c;…

Redis源码分析之网络模型

Redis网络模型 阅读源码的初衷Redis源码阅读 阅读源码的初衷 很多网上解释这个Redis为啥这么块&#xff1f;都会说Redis这么快的原因会有一个Redis才用了单线程&使用了多路io复用来检查io事件&#xff0c;单线程可以避免多线程对资源的竞争。如果我们使用了多线程那么就需…

ChatGPT其实并不想让开发人员做这5件事情

前言 ChatGPT已经火爆了快半年了吧&#xff0c;紧接着国内也开始推出了各种仿制品&#xff0c;我甚至一度怀疑&#xff0c;如果人家没有推出ChatGPT&#xff0c;这些仿制品会不会出现。而很多人也嗨皮得不行&#xff0c;利用各种方法开始科学上网&#xff0c;用ChatGPT做各种觉…

[读书笔记] Variational AutoEncoders

小全读书笔记 《Variational AutoEncoders》 1. Generative Model &#xff08;生成式模型&#xff09;简述2. 简单生成模型 AutoEncoders2.1 结构2.2 不足 3. Variational AutoEncoders4. Variational AutoEncoders的数学支持 此读书笔记来自于Joseph Rocca的Understanding Va…

APP 兼容性测试是什么?8年测试老鸟告诉你

1、APP 兼容性测试认识 随着 APP 应用范围越来越广&#xff0c;用户群体越来越大&#xff0c;终端设备的型号也越来越多&#xff0c;移动终端碎片化加剧&#xff0c;使得 APP 兼容性测试成为测试质量保障必须要考虑的环节。 APP 兼容性测试通常会考虑&#xff1a;操作系统、厂…

js执行思维导图

备注&#xff1a; js执行&#xff1a; 执行分为两部分&#xff1a;预执行和执行 预执行&#xff1a;创建好执行上下文 执行&#xff1a;执行栈中执行 js引擎&#xff1a; 读取并执行js 各个浏览器的引擎如下 …

linux学习[10]磁盘与文件系统(1):查看磁盘容量指令df 评估文件系统的磁盘使用量指令 du

文章目录 前言1. df指令2. du指令 前言 TF卡制作的过程中涉及到了磁盘分区格式化等问题&#xff0c;当时对具体的指令理解不是特别深刻&#xff1b;由此引申到我对linux中的整个磁盘与文件系统没有一个全面的认识&#xff0c;这个磁盘与文件系统的系列博客章节就对这些进行记录…

MySQL的主从复制与读写分离

一、MySQL主从复制 1、mysql支持的复制类型 STATEMENT∶基于语句的复制。在服务器上执行sql语句&#xff0c;在从服务器上执行同样的语句&#xff0c;mysql默认采用基于语句的复制&#xff0c;执行效率高。 ROW∶ 基于行的复制。把改变的内容复制过去&#xff0c; 而不是把命…

下载和安装appuploader

转载&#xff1a;下载和安装appuploader IOS开发工具官网地址 Appuploader home -- A tool improve ios develop efficiency such as submit ipa to appstore and manage ios certificate 最新版本已经优化了没支付688给apple的账号登录流程&#xff0c;无需再安装其他软件。…

微服务保护(线程隔离、降级、熔断)

线程隔离 线程隔离有两种方式实现: 线程池隔离信号量隔离 线程池隔离 假设服务A依赖于服务B和服务C&#xff0c;那么服务A就会分别对服务B和服务C创建线程池&#xff0c;当有请求进来时不会使用服务A本身的线程&#xff0c;而是到对应的线程池中取一个线程来调用feign的客户…

AMBER分子动力学模拟之TOP准备-- HIV蛋白酶-抑制剂复合物(1)

AMBER分子动力学模拟之TOP准备-- HIV蛋白酶-抑制剂复合物(1) 我们以HIV蛋白酶-抑制剂复合物为例子&#xff0c;跑Amber动力学模拟 下载1phv 从PBD下载文件&#xff1a;https://www.rcsb.org/ PDB文件预处理 我们以 “protein(water) ligandcomplex” 为例来说一下如何处…

力扣82删除排序链表中的重复元素 II:思路分析+代码实现+方法总结(三指针法快慢指针法【双指针】递归法)

文章目录 第一部分&#xff1a;题目描述第二部分&#xff1a;代码实现2.1 三指针法2.2 快慢指针法&#xff08;双指针&#xff09;2.3 递归 第一部分&#xff1a;题目描述 &#x1f3e0; 链接&#xff1a;82. 删除排序链表中的重复元素 II - 力扣&#xff08;LeetCode&#xf…

ChatGPT热门资料汇总,绝对不割韭菜

前言 ChatGPT 的出现&#xff0c;AI圈子一下就热闹起来了&#xff0c;各个公司争先恐后地出自己的产品&#xff0c;百度的文心一言、谷歌的Bard、阿里的通义千问等等&#xff0c;有很多人借此机会已经赚到百万&#xff0c;很多卖课搞培训的都是互为合伙人&#xff0c;大家都懂…

如何注册appuploader账号​

如何注册appuploader账号​ 我们上一篇讲到appuploader的下载安装&#xff0c;要想使用此软件呢&#xff0c;需要注册账号才能使用&#xff0c;今​ 天我们来讲下如何注册appuploader账号来使用软件。​ 1.Apple官网注册Apple ID​ 首先我们点击首页左侧菜单栏中的“常见网…

【更新日志】填鸭表单TduckPro v5.1 更新

hi&#xff0c;各位Tducker小伙伴。 填鸭表单pro迎来了v5.1版本&#xff1b;本次我们进行了许多的功能新增和优化&#xff0c;能够让我们在日常使用中获得更好的体验。 让我们一起来康康新功能吧。 01 新增Pro功能 新增登录后才能填写表单。 新增表单卡片一键发布。 新增矩…

【STM32CubeMX】F103窗口看门狗

前言 本文记录了我学习STM32CubeMX的过程&#xff0c;方便以后回忆。我们使用的开发板是基于STM32F103C6T6的。本章记录了窗口看门狗的使用配置。要学习的话&#xff0c;注意流程一说&#xff0c;省略的内容。 基础 窗口看门狗(WWDG)属于APB1上外设。窗口看门狗(WWDG)的时钟源…