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

这篇具有很好参考价值的文章主要介绍了Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.什么是painless

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

es的版本与脚本的演化过程:
Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本),Elasticsearch,# kibana,elasticsearch,java,大数据,kibana
本文仅介绍常用的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

Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本),Elasticsearch,# kibana,elasticsearch,java,大数据,kibana
建立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;"
      }
    }
  }
}

脚本查询结果如下:
Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本),Elasticsearch,# kibana,elasticsearch,java,大数据,kibana

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']"
      }
    }
  }
}

Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本),Elasticsearch,# kibana,elasticsearch,java,大数据,kibana

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

关于脚本查询须知

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

5.1 字段更新脚本

需求描述:原始文档中的coreJournal字段中值存在空格,现在要求将空格去除
实现步骤:首先根据查询条件为存在coreJournal字段的文档,然后再对coreJournal中的值进行遍历去除空格操作文章来源地址https://www.toymoban.com/news/detail-577066.html

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": []
    }
  }
}

执行效果如下:
Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本),Elasticsearch,# kibana,elasticsearch,java,大数据,kibana

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": []
    }
  }
}

执行效果如下:
Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本),Elasticsearch,# kibana,elasticsearch,java,大数据,kibana

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

到了这里,关于Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Elasticsearch的子聚合查询和使用SpringDataElasticSearch如何实现三级的子查询

    文档中存在字段year(年),volume(卷),issue(期)三个字段,现有需求如下:需要先根据year进行聚合并且降序,然后根据volume字段在年聚合后再次聚合,issue字段则在以上两字段的聚合后再次聚合,效果图如下: 检索结果: 实现效果: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/

    2024年02月16日
    浏览(38)
  • Linux下ElasticSearch7.9.2安装配置(包含服务器配置、启动停止脚本、开放端口和elasticsearch-head插件的使用)

    本文主要介绍Linux下ElasticSearch7.9.2安装,目前是介绍单节点的配置 应用 版本 说明 操作系统 centos7 稳定、高预测性、高管理性、高重复性的Linux平台 elasticsearch 7.9.2 es7.x的linux版本 jdk 8 本人使用JDK 8;ES建议使用JDK 11 启动的时候会有警告但是不会报错,可以忽略 此种方式可能比

    2024年02月08日
    浏览(62)
  • Elasticsearch-06-Elasticsearch Java API Client-Elasticsearch 8.0 的api

    在 Elasticsearch7.15版本之后,Elasticsearch官方将它的 高级客户端 RestHighLevelClient 标记为弃用状态。同时推出了全新的 Java API客户端 Elasticsearch Java API Client ,该客户端也将在 Elasticsearch8.0及以后版本中成为官方推荐使用的客户端。 Elasticsearch Java API Client 支持除 Vector tile search API 和

    2024年04月11日
    浏览(37)
  • Elasticsearch8.x版本Java客户端Elasticsearch Java API Client中常用API练习

    在Es7.15版本之后,es官方将它的高级客户端RestHighLevelClient标记为弃用状态。同时推出了全新的java API客户端Elasticsearch Java API Client,该客户端也将在Elasticsearch8.0及以后版本中成为官方推荐使用的客户端。 Elasticsearch Java API Client支持除Vector title search API和Find structure API之外的所有

    2024年04月11日
    浏览(49)
  • ElasticSearch系列——Elasticsearch Java API Client

    这是用于Elasticsearch的官方Java API客户端的文档。客户端为所有Elasticsearch API提供强类型请求和响应。我们要注意原来的HighRestAPIClient以及停用了,这是趋势,包括SpringData-ElasticSearch4.4.5之后配合ES8的推出也会更换 https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/7.17/indexing.html

    2024年02月01日
    浏览(44)
  • java调用elasticSearch api

    java操作es有两种方式 通过操作es的9300端口,9300是tcp端口,集群节点之间通信也是通过9300端口,会通过9300和es建立一个长连接,下面的es的依赖可以直接操作 但是随着es的版本的提升spring-data需要封装不同版本的es的jar包,好像还没封装到这个版本(2019),另外官方也不推荐通

    2024年02月02日
    浏览(43)
  • java Api操作Elasticsearch

    本次使用 elasticsearch 版本为7.17.0, 建议使用 7.X 版本 ,8.1.2版本会遇到一些 Springboot(本人使用版本2.6.6) 版本不兼容的问题。此文章会列举一个例子。 我们在测试类中先创建一个客户端,用来向 ES 发送请求 测试代码如下: 控制台输出信息如下: 此处会遇到坑: 运行之后

    2023年04月09日
    浏览(40)
  • ElasticSearch java API - 聚合查询

    }, “low”: { “type”: “long” }, “date”: { “format”: “strict_date_optional_time||epoch_millis”, “type”: “date” }, “close”: { “type”: “long” } }, “_all”: { “enabled”: false } } } 索引中的全部数据: name age salary team position james 33 3000 cav sf irving 25 2000 cav pg curry 29 1000 war pg thompson 26

    2024年04月10日
    浏览(38)
  • Java API批量操作Elasticsearch

    @Test public void batchAddIndex() throws IOException { BulkRequestBuilder bulkRequest = client .prepareBulk(); bulkRequest.add( client .prepareIndex( “batch_test1” , “batch” , “1” ) .setSource( jsonBuilder () .startObject() .field( “user” , “lzq” ) .field( “postDate” , new Date()) .field( “message” , “trying out Elasticsearch”

    2024年04月09日
    浏览(45)
  • Elasticsearch分组--- java api 实现

    这篇文章 将已实战的方式带你 实现es 的各种分组操作

    2024年02月12日
    浏览(71)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包