Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Elasticsearch中,Painless脚本通常用于计算评分、排序、聚合或者其他计算任务

Elasticsearch中,Painless脚本通常用于计算评分、排序、聚合或者其他计算任务

作者头像
小冷coding
发布于 2024-05-14 04:31:08
发布于 2024-05-14 04:31:08
75310
代码可运行
举报
文章被收录于专栏:小冷coding小冷coding
运行总次数:0
代码可运行
最近在开发过程中遇到这样的一个小需求,给商品进行分组,每一组有不同的数量的商品,每个组要进行排序,每一组的商品也要进行排序。

商品的数据存储在ES中,需要通过spuIds进行排序查询数据返回。这时就需要用到ES中的排序部分,它需要使用一个Painless脚本,根据传递的参数值对id进行排序。

最终正确返回的数据结构如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 {
            "id": "3",
            "name": "第1组",
            "spuIds":  [19, 7, 20, 10, 2, 6, 3, 18, 9, 8, 1],
            "backgroundColor": "#1677FF",
            "productPages": {
                "data":[
                     {
                      "id": "19",
                      "spuId": "1106",
                      "skuId": "1106",
                      "name": "人工牛黄甲硝唑胶囊",
                      "price": 39.9,
                      "underlinedPrice": 78.0,
                      "shopId": "27"
                     },.....],
                  "totalCount": 15,
                  "pageSize": 10,
                  "totalPages": 2,
                  "nextPage": false,
                  "current": 2
             },
            "nextPage": true,
            "sort": 7
        }

在Elasticsearch中,Painless是一种安全、沙盒化的脚本语言,专门用于执行复杂的计算和操作。Painless的设计目标是提供一个功能强大但又足够安全的脚本环境,以便在Elasticsearch查询和聚合中执行自定义逻辑。

以下是Painless脚本在Elasticsearch中的一些常见用途:

计算评分:在搜索查询中,你可以使用Painless脚本来定义自定义的评分函数,从而影响文档的排序和排名。例如,你可以根据文档的某个字段值或其他计算来调整文档的得分。

排序:除了默认的基于字段值的排序外,你还可以使用Painless脚本来定义更复杂的排序逻辑。这意味着你可以根据文档内容的计算结果或其他动态条件对搜索结果进行排序。

聚合:在聚合查询中,Painless脚本可以用来定义聚合的桶键(bucket keys)或度量(metrics)。这允许你根据文档内容的计算结果来分组或计算聚合结果。

脚本字段:你可以使用Painless脚本来动态地添加或修改搜索结果的字段。这对于在搜索结果中包含计算后的值或格式化后的数据非常有用。

更新文档:虽然不推荐频繁使用脚本来更新文档,但在某些情况下,你可以使用Painless脚本来执行简单的文档更新操作。

需要注意的是,虽然Painless脚本提供了很大的灵活性,但过度使用或不当使用可能会对Elasticsearch集群的性能和稳定性产生负面影响。因此,在设计查询和聚合时,应谨慎使用脚本,并尽可能优化其性能。

因此这次Elasticsearch的DSL查询用到的脚本如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET /spu/_search
{
  "from": 0,
  "size": 5,
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "id": [19, 7, 20, 10, 2, 6, 3, 18, 9, 8, 1]
          }
        },
        {
          "term": {
            "status": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "sort": [
    {
      "_script": {
        "script": {
          "source": "return params.doc['id'].value",
          "lang": "painless",
          "params": {
            "1": 10,
            "2": 4,
            "3": 6,
            "6": 5,
            "7": 1,
            "8": 9,
            "9": 8,
            "10": 3,
            "18": 7,
            "19": 0,
            "20": 2
          }
        },
        "type": "number",
        "order": "asc"
      }
    }
  ]
}

你会发现params是一个Map结构,通过id进行查询排序的。

params中key就是spuId里面的参数,value就是排序的数值。

Java中如何实现呢?代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        //query.getSpuIds()查询条件
        int size = query.getSpuIds().size();
        Map<String, Object> scriptParams = new HashMap<>(size);
        for (int i = 0; i < size; i++) {
            scriptParams.put(String.valueOf(query.getSpuIds().get(i)), i);
        }
        // 构建排序脚本
        ScriptSortBuilder scriptSortBuilder = new ScriptSortBuilder(new Script(ScriptType.INLINE, "painless",
                "return params[doc['id'].value+'']",
                scriptParams), ScriptSortBuilder.ScriptSortType.NUMBER);
        // 执行查询
        queryBuilder.withPageable(PageRequest.of(query.getCurrent() - 1, query.getPageSize()));
        queryBuilder.withSort(scriptSortBuilder);

写到这里问题就解决了,前台页面就能很好地展示分页结构了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小冷coding 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
可以,大佬,互粉一下
可以,大佬,互粉一下
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
Elasticsearch: Painless script编程
我们之前看见了在 Elasticsearch 里的 ingest node 里,我们可以通过以下 processor 的处理帮我们处理我们的一些数据。它们的功能是非常具体而明确的。那么在 Elasticsearch 里,有没有一种更加灵活的方式可供我们来进行编程处理呢?如果有,它使用的语言是什么呢?
腾讯云大数据
2020/09/28
3.1K0
Elasticsearch: Painless script编程
es painless 排序_Elasticsearch中使用painless实现评分「建议收藏」
使用Elasticsearch(ES)作为搜索引擎时我们常常需要根据文档的属性值自定义它们的排序,为用户提供高质量的搜索结果。
全栈程序员站长
2022/07/23
7320
学好Elasticsearch系列-脚本查询
Elasticsearch的 Scripting 是一种允许你使用脚本来评估自定义表达式的功能。通过它,你可以实现更复杂的查询、数据处理以及柔性调整索引结构等。
BookSea
2023/08/15
6380
学好Elasticsearch系列-脚本查询
Elasticsearch:Painless scripting 高级编程
在之前的文章中,我介绍了 Painless 脚本编程,并提供了有关其语法和用法的详细信息。 它还涵盖了一些最佳实践,例如,为什么使用参数,何时访问文档字段时何时使用 “doc” 值而不是 “ _source” 以及如何动态创建字段等。
腾讯云大数据
2020/11/12
1.8K0
Elasticsearch:Painless scripting 高级编程
elasticsearch painless最强教程
ElasticStack在升级到5.0版本之后,带来了一个新的脚本语言,painless。这里说“新的“是相对与已经存在groove而言的。还记得Groove脚本的漏洞吧,Groove脚本开启之后,如果被人误用可能带来各种漏洞,为什么呢,主要是这些外部的脚本引擎太过于强大,什么都能做,用不好或者设置不当就会引起安全风险,基于安全和性能方面,所以elastic.co开发了一个新的脚本引擎,名字就叫Painless,顾名思义,简单安全,无痛使用,和Groove的沙盒机制不一样,Painless使用白名单来限制函数与字段的访问,针对es的场景来进行优化,只做es数据的操作,更加轻量级,速度要快好几倍,并且支持Java静态类型,语法保持Groove类似,还支持Java的lambda表达式。
全栈程序员站长
2022/07/22
7830
elasticsearch painless最强教程
探究 | Elasticsearch Painless 脚本 ctx、doc、_source 的区别是什么?
上述问题不止一次被问到,我自己在使用 painless 脚本的时候,也会遇到上述困惑。
铭毅天下
2021/12/09
4.3K0
探究 | Elasticsearch Painless 脚本 ctx、doc、_source 的区别是什么?
Elasticsearch:Painless 编程调试「建议收藏」
Painless 也就是无痛的意思。这是一个专为 Elasticsearch 而设计的。当初的设计人员取名为 “Painless”,表达的意思的是在编程的时候没有疼痛感,很方便设计人员使用。由于这是一个脚本的语言,在实际的使用中,我们很难找到这些编程的方法及使用。在今天的教程中,我来讲述一下该如何来进行调试。
全栈程序员站长
2022/08/01
1.2K0
Elasticsearch 8.X:这个复杂的检索需求如何实现?
如上图所示,index中有这样四个字段:title content question answer。要查询这四个字段,支持最多输入5个关键词模糊查询,多关键词以空格隔开。
铭毅天下
2023/09/26
5490
Elasticsearch 8.X:这个复杂的检索需求如何实现?
深入解析Elasticsearch中脚本原理
Elasticsearch作为一个分布式搜索和分析引擎,以其强大的全文搜索、结构化搜索和分析能力而广受欢迎。在Elasticsearch中,脚本是一种强大的工具,允许用户在查询和索引操作中执行动态计算和数据处理。从Elasticsearch 7.6版本开始,脚本功能得到了进一步的优化和提升,为用户提供了更加灵活和高效的数据处理方式。
公众号:码到三十五
2024/03/19
3250
painless数字类型转换_笔记四十五: Ingest Pipeline 与 Painless Script
Tags 字段中,逗号分割的文本应该是数组,而不是一个字符串需求:后期需要对 Tags 进行 Aggregation 统计
全栈程序员站长
2022/07/23
1.3K0
Elasticsearch使用:Scripting API(二)
我们之前看见了在 Elasticsearch 里的 ingest node 里,我们可以通过以下 processor 的处理帮我们处理我们的一些数据。它们的功能是非常具体而明确的。那么在 Elasticsearch 里,有没有一种更加灵活的方式可供我们来进行编程处理呢?如果有,它使用的语言是什么呢?
HLee
2021/01/12
1.4K0
Elasticsearch使用:Scripting API(二)
Elasticsearch 企业级实战 01:Painless 脚本如何调试?
Painless 是 Elasticsearch 的内置脚本语言,虽然强大,但调试起来并不容易。
铭毅天下
2024/07/16
3220
Elasticsearch 企业级实战 01:Painless 脚本如何调试?
Elasticsearch 8.X 如何基于用户指定 ID 顺序召回数据?
原生的 Elasticsearch 检索机制没有这个功能。那就意味着,咱们得自己实现。
铭毅天下
2023/08/18
5960
Elasticsearch 8.X 如何基于用户指定 ID 顺序召回数据?
快速学习ES6-Spring Data Elasticsearch
而是学习Spring提供的套件:Spring Data Elasticsearch。
cwl_java
2020/02/11
1.8K0
ElasticSearch[八]:自定义评分功能、使用场景讲解以及 function_score常用的字段解释
ES 的使用中,ES 会对我们匹配文档进行相关度评分。但对于一些定制化的场景,默认评分规则满足不了我们的要求。这些定制化场景,ES 也是推出了自定义评分方式来进行支持。可以使用 ES 提供的一些函数,什么可以使用较分来让我们的评分规则多样化。我举个大家都很熟悉的场景,在点外卖时候,大家是不是有一个综合排序,比如用户希望通过距离和价格来进行综合排序,这在 mysql 中是不是比较难以实现,接下来我将由简到繁的来教你如何在 ES 中实现这种综合评分排序的功能
汀丶人工智能
2024/01/20
1.3K0
ElasticSearch[八]:自定义评分功能、使用场景讲解以及 function_score常用的字段解释
干货 | Elasticsearch7.X Scripting脚本使用详解
除了官方文档,其他能找到的介绍Elasticsearch脚本(Scripting)的资料少之又少。
铭毅天下
2019/09/17
15.5K1
干货 | Elasticsearch Nested 数组大小求解,一网打尽!
https://www.elastic.co/guide/en/elasticsearch/reference/8.0/query-dsl-nested-query.html
铭毅天下
2022/04/06
1.7K3
干货 | Elasticsearch Nested 数组大小求解,一网打尽!
Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?
如下所示, 希望在查出的结果后, 对结果进行后处理,对tags列表,根据depth进行排序。
铭毅天下
2024/01/11
7860
Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?
Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询
在 Elasticsearch 中,cardinality 算法用来计算字段的基数(不重复的值的个数).
小小工匠
2023/05/12
1.4K0
Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询
快速入门ElasticSearch
最近事情比较多,好久没更新文章,现在失踪人口回归,开始日常更新文章,一周不低于两篇,同时内容不限于Python,会有好多有趣的技术等着去学习和发现~~~
啃饼思录
2020/10/23
1.9K0
快速入门ElasticSearch
推荐阅读
相关推荐
Elasticsearch: Painless script编程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验