• ElasticSearch笔记脚本(script)


    使用场景

    用于解决复杂业务问题,如:自定义字段、自定义评分、自定义更新、自定义聚合分析等

    缺点

    性能问题。官方文档性能优化中明确指出使用脚本会导致性能低;
    如非必要,不要使用脚本,尽量用其他方式替换,如下:
    使用脚本进行前缀查询:

     1POST seats/_search
     2{
     3 "query": {
     4  "bool":{
     5    "filter": { 
     6    "script":{
     7      "script":{
     8        "lang":"painless",
     9        "source": "doc['theatre'].value.startsWith('Down')"
    10      }
    11    }
    12    }
    13  }
    14 }
    15}
    

    可以使用prefix前缀匹配,性能提升5倍

    script模板

    "script": {
        "lang":   "...",  
        "source" | "id": "...", 
        "params": { ... } 
    }
    

    lang:代表language脚本语言,默认指定为:painless。
    source:脚本的核心部分,id应用于:stored script。
    params:传递给脚本使用的变量参数。

    Painless Scripting 简介

    Painless是一种简单,安全的脚本语言,专为与Elasticsearch一起使用而设计。从ES5.0开始,它是Elasticsearch的默认脚本语言,可以安全地用于内联和存储脚本。
    Painless特点:
    性能牛逼:Painless脚本运行速度比备选方案(包括Groovy)快几倍。
    安全性强:使用白名单来限制函数与字段的访问,避免了可能的安全隐患。
    可选输入:变量和参数可以使用显式类型或动态def类型。
    上手容易:扩展了java的基本语法,并兼容groove风格的脚本语言特性。
    特定优化:是ES官方专为Elasticsearch脚本编写而设计。

    存储脚本

    脚本可以使用_scripts端点存储在集群状态中并从集群状态检索。
    下面是使用位于/_scripts/{id}的存储脚本的示例。
    首先,在集群状态下创建名为calculate-score的脚本:

    POST _scripts/calculate-score
    {
      "script": {
        "lang": "painless",
        "source": "Math.log(_score * 2) + params.my_modifier"
      }
    }
    

    同样的获取脚本可以用:

    GET _scripts/calculate-score
    

    存储的脚本可以通过如下方式指定id参数来使用:

    GET _search
    {
      "query": {
        "script": {
          "script": {
            "id": "calculate-score",
            "params": {
              "my_modifier": 2
            }
          }
        }
      }
    }
    

    删除脚本

    DELETE _scripts/calculate-score
    

    案例

    自定义字段

    返回原有Mapping未定义的字段值。
    1.1、以idplus返回id字段的翻倍后的结果。

    GET index6/_search
    {
      "script_fields": {
        "idplus": {
          "script": {
            "lang": "expression",
           "source": "doc['id'] * multiplier",
             "params": {
               "multiplier": 2
            }
          }
        }
      }
    }
    

    结果

    {
    省略...
        "hits" : [
          {
            "_index" : "index6",
            "_type" : "_doc",
            "_id" : "2001",
            "_score" : 1.0,
            "fields" : {
              "idplus" : [
                4002.0
              ]
            }
          },
    省略...
        ]
    }
    

    1.2、返回日期字段中的“年”或“月”或“日”等。

     1GET hockey/_search
     2{
     3  "script_fields": {
     4    "birth_year": {
     5      "script": {
     6        "source": "doc.born.value.year"
     7      }
     8    }
     9  }
    10}
    

    自定义评分

    1GET my_index/_search
     2{
     3  "query": {
     4    "function_score": {
     5      "query": {
     6        "match": {
     7          "text": "quick brown fox"
     8        }
     9      },
    10      "script_score": {
    11        "script": {
    12          "lang": "expression",
    13          "source": "_score * doc['popularity']"
    14        }
    15      }
    16    }
    17  }
    18}
    

    自定义更新

    1.1、_update:将已有字段值赋值给其他字段。

     POST index6/_update/1
     {
       "script": {
         "lang": "painless",
         "source": """
           ctx._source.firstName = params.firstName;
           ctx._source.lastName = params.lastName
         """,
         "params": {
          "firstName": "aa",
          "lastName": "bb"
        }
      }
    }
    

    1.2、Update_by_query:满足b开头(注意正则)的字段,末尾添加matched。

     1POST hockey/_update_by_query
     2{
     3  "script": {
     4    "lang": "painless",
     5    "source": """
     6      if (ctx._source.last =~ /b/) {
     7        ctx._source.last += "matched";
     8      } else {
     9        ctx.op = "noop";
    10      }
    11    """
    12  }
    13}
    

    自定义reindex

    Elasticsearch认证考试题:
    有index_a包含一些文档, 要求创建索引index_b,通过reindex api将index_a的文档索引到index_b。
    要求:
    1)增加一个整形字段,value是index_a的field_x的字符长度;
    2)再增加一个数组类型的字段,value是field_y的词集合。
    (field_y是空格分割的一组词,比方"foo bar",索引到index_b后,要求变成["foo", "bar"])

    1POST _reindex
     2{
     3  "conflicts": "proceed",
     4  "source": {
     5    "index": "index_a"
     6  },
     7  "dest": {
     8    "index": "index_b"
     9  },
    10  "script": {
    11    "source": "ctx._source.parts = / /.split(ctx._source.address); ctx._source.tag = ctx._source.city.length();"
    12  }
    13}
    

    自定义聚合

     1GET /_search
     2{
     3    "aggs" : {
     4        "genres" : {
     5            "terms" : {
     6                "script" : {
     7                    "source": "doc['genre'].value",
     8                    "lang": "painless"
     9                }
    10            }
    11        }
    12    }
    13
    14}
    
  • 相关阅读:
    石子合并问题(直线版)
    Python_07-常用函数
    Python_06-函数与模块
    C++中的头文件和源文件
    sell 项目 商品表 设计 及 创建
    SpringBoot集成Mybatis
    SpringBoot集成jdbcTemplate/JPA
    SpringBoot使用JSP渲染页面
    SpringBoot引入freemaker前端模板
    使用SpringBoot创建Web项目
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/14503125.html
Copyright © 2020-2023  润新知