elasticsearch_script_01

2023-11-11

1. script 简述

elasticsearch的script使用比较灵活而且广泛,有必要先了解和学习一下

1. script的类型和作用

script 可以让你自定义的返回一些field,也可以让你自定义score的计算。
在es中可以使用的script的类型有三种,就像是三种编程语言一样

  1. painless: 这个是最推荐的一种方式
  2. expression: lucene expression
  3. mustache: 这个一般用来定义search_template使用
  4. java

painless 是效率比较好,也比较灵活的一种。后面介绍script的功能的时候也主要以这个为主进行介绍。

2. script使用的方式


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

source 部分是script的代码或者是 使用id,调用存储的script的id。

2. script的使用场景

在不同的使用场景下script能够使用的doc的field是不相同的。

1. update scripts

在update, update-by-query, reindex API可以通过ctx前缀获取到

  1. ctx._source : doc的_source 字段
  2. ctx.op : 当前操作,index/delete/noop
  3. ctx._index 等: doc的meta-fields,有些是只读的

2. search 和agg 中使用script

script fields 会在每个搜索命中的doc执行一次,其他在search和agg中使用的脚本将针对可能与search或agg匹配的每个文档执行一次,所有的普通字段值可以通过下面方式获取

  1. doc-values : 获取方式为doc[‘cost_price’].value,只有有doc_value的字段才可以这样使用,text字段理论上不能这样用
  2. the _source field : params._source.first_name 这里的params前缀必须要有
  3. stored fields : params._fields[‘first_name’].value

同时还可以在一些特定的查询中获取比如score等字段

3. search中获取doc的打分数据

获取和修改文档的_score字段只能够在 function_score query, script-based sorting, 或者 aggregations 当中
具体的使用方式有不太相同,在function_score中使用 script_score属性,在script-based sorting 中使用_script 属性

script语法,点号“.”表示获取字段,中括号表示获取数组“[]”,对应的样例就是
params._source.first_name
params._fields[‘first_name’].value

3. script灵活使用的一些理解

script可以简单的理解像java一样
常见的数据类型有

  1. 字符串:对应的方法有.length() 方法
  2. 数组[]: 对应的属性有.length 对应的方法有.add() .size() 可以试试看看对应于field的value是不是可以添加元素,可能是根据现有field value的类型来决定的
  3. 正则:/aa/.split(str) 这个也太复杂了,就是java正则的使用,感觉一般情况先应该用不上吧。
  4. 数字

script的逻辑表达式只有两种

  1. if else
  2. for 循环

语法

int x;           
List y;          add(ele) get(1)  y[1]=5  y.length()
int x, y = 5, z; 
def d;           
int i = 10;      
float[] f;      f[0]  f.length  数组类型
Map[][] m;      get(key) m['a']='b'  m.a='a_value'
String r = "some text" 

这个语法有点类似python的语法,比较简练

4. script的使用方式

  1. 直接在某些query中使用script关键字
  2. search中使用script来产生额外的field使用的script_field关键字,然后再嵌套使用script关键字
  3. search的function_score中使用script来自定义score时候使用的script_score关键字,然后再嵌套使用script关键字
  4. search中使用script来产生sort字段的时候在sort字段中嵌套使用_script关键字,然后再嵌套使用 script关键字

5. 样例

1. 在search中使用 script_score功能

在 function_score 查询, script-based 排序(sorting), 或者 aggregations 有能力获取到 _score 字段
需要使用script_score 查询。
比如下面 是在function_score 中改变_score,其他类型的将来遇到再看


PUT my_index/_doc/1?refresh
{
  "text": "quick brown fox",
  "popularity": 1
}


PUT my_index/_doc/2?refresh
{
  "text": "quick fox",
  "popularity": 5
}

PUT my_index/_doc/3?refresh
{
  "text": "quick fox",
  "popularity": 50
}

GET my_index/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "text": "quick brown fox"
        }
      },
      "script_score": {
        "script": {
          "lang": "expression",
          "source": "_score * doc['popularity']"
        }
      }
    }
  }
}

返回


{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 4.0225573,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 4.0225573,
        "_source" : {
          "text" : "quick fox",
          "popularity" : 50
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.2483562,
        "_source" : {
          "text" : "quick brown fox",
          "popularity" : 1
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.4022557,
        "_source" : {
          "text" : "quick fox",
          "popularity" : 5
        }
      }
    ]
  }
}


script base sorting

GET /_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    },
    "sort" : {
        "_script" : {
            "type" : "number",
            "script" : {
                "lang": "painless",
                "source": "doc['field_name'].value * params.factor",
                "params" : {
                    "factor" : 1.1
                }
            },
            "order" : "asc"
        }
    }
}

agg操作等后面再总结。

2. 获取field的value,通过doc values

使用 doc[‘field_name’]
但是因为string.text field 没有doc-values 所以如果想用这种方式获取的话需要打开 fielddata 设置,这是一个很昂贵的操作。所以尽量不要使用script获取text field的内容。


PUT my_index/_doc/1?refresh
{
  "cost_price": 100
}

GET my_index/_search
{
  "script_fields": {
    "sales_price": {
      "script": {
        "lang":   "expression",
        "source": "doc['cost_price'] * markup",
        "params": {
          "markup": 0.2
        }
      }
    }
  }
}

3. 获取field value 通过_source字段

通过_source.field_name 可以获取到source中对应的字段,但是相对来说比doc-values的要慢很多。

PUT my_index
{
  "mappings": {
    "properties": {
      "first_name": {
        "type": "text"
      },
      "last_name": {
        "type": "text"
      }
    }
  }
}

PUT my_index/_doc/1?refresh
{
  "first_name": "Barry",
  "last_name": "White"
}

GET my_index/_search
{
  "script_fields": {
    "full_name": {
      "script": {
        "lang": "painless",
        "source": "params._source.first_name + ' ' + params._source.last_name"
      }
    }
  }

返回主体
"hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "fields" : {
          "full_name" : [
            "Barry White"
          ]
        }
      }
    ]

上面的script.source中还必须要带params。

4. 获取field value 通过store field

store field是指那些在mapping中定义的mapping param 为 store:true的field
可以使用 _fields[‘field_name’].value or _fields[‘field_name’] 语法

PUT my_index
{
  "mappings": {
    "properties": {
      "full_name": {
        "type": "text",
        "store": true
      },
      "title": {
        "type": "text",
        "store": true
      }
    }
  }
}

PUT my_index/_doc/1?refresh
{
  "full_name": "Alice Ball",
  "title": "Professor"
}

GET my_index/_search
{
  "script_fields": {
    "name_with_title": {
      "script": {
        "lang": "painless",
        "source": "params._fields['title'].value + ' ' + params._fields['full_name'].value"
      }
    }
  }
}


source field也是 store field的一种,所以_source field的性能和store field的性能接近,使用store filed的唯一场景是 _source特别大,我们并不需要获取全部的_source的时候 使用store field会更好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

elasticsearch_script_01 的相关文章

随机推荐

  • 使用docker方式安装FastDFS

    FastDFS 架构包括 Tracker server 和 Storage server 客户端请求 Tracker server 进行文件上传 下载 通过 Tracker server 调度 最终由 Storage server 完成文件
  • 时钟天气小插件显示没服务器,天气时钟小插件大全

    有没有好用的天气时钟插件 首先右击桌面选排列图标 勾选显示桌面图标 2 如果故障依旧 打开任务管理器 按下 Ctrl Alt Del 组合键即可打开 点击 文件 新建任务 在打开的 创建新任务 对话框中输入 explorer 单击 确定 按
  • windows docker wsl2的docker内存占用大

    windows docker wsl2的docker内存占用大 1重启wsl2 最终采用 实测直接stop运行的docker实例 并不会减少Vmmem内存 因此需要重启wsl2 输入wsl shutdown即可 同时把Docker Desk
  • Vs QT 程序添加按钮控件,及使用信号和槽

    include QtWidgetsApplication1 h include
  • 基于python的分布式实现多节点资产收集管理平台

    真正的大师 永远都怀着一颗学徒的心 一 项目简介 基于python的分布式实现多节点资产收集管理平台 二 实现功能 支持域名扫描 支持备案信息查询 支持fofa查询 支持多账号管理 支持web站点扫描 支持目录扫描 支持端口扫描 支持漏洞扫
  • ESP32 ADC –使用Arduino IDE读取模拟值

    本文介绍了如何使用Arduino IDE通过ESP32读取模拟输入 模拟读取对于从电位计或模拟传感器等可变电阻读取值非常有用 模拟输入 ADC ADC是非线性的 analogRead 函数 其他有用的功能 使用ESP32从电位计读取模拟值
  • MySQL 事务隔离级别,读现象,MVCC

    目录 数据库读现象 事务隔离级别 错误日志 详情参见 MySQL日志管理 JasonJi 博客园 mvcc多版本并发控制 多版本并发控制mvcc multi version concurrency controll 基于多版本的并发控制 在
  • 区块链应用开发入门

    区块链技术如今是非常火热 不仅让金融家和创投家趋之若鹜 如今已经在多个领域遍地播种 作为拥有锐利触角的创业家们 是否也想将区块链集成到你们现有的应用中去 而作为IT技术工程师的你 是否也是跃跃欲试 想基于区块链来练一下手 以免日后被新技术淘
  • tcpdump: syntax error 解决-linux 下安装tcpdump 和 libpcap

    关键 linux 如何下载包 wget 下载指定目录 linu 下载文件到指定目录 今天心血来潮突然想在自己的服务上抓某个端口 结果执行tcpdump时报错了 http www tcpdump org index html 找到Latest
  • 基于C语言的分页管理方式下存储分配情况模拟

    1 题目简介 借用外存空闲分区管理中位示图的方法来表示主存分配情况 实现主存空间的分配和回收 要求能显示和打印分配或回收前后的位示图和当前空闲块数 对完成一次分配后还要显示或打印为作业建立的页表 2 所用数据结构 为要分配的作业建立数据结构
  • 时钟抖动(Jitter)和时钟偏斜(Skew)

    在进行时序分析时 经常会遇到两个比较容易混淆的概念 那就是时钟抖动 Clock Jitter 和时钟偏斜 Clock Skew 下面就解释下两者的区别 一 Jitter 由于晶振本身稳定性 电源以及温度变化等原因造成了时钟频率的变化 指的是
  • ipc_perm 详解

    系统为每一个IPC对象保存一个ipc perm结构体 该结构说明了IPC对象的权限和所有者 每一个版本的内核各有不用的ipc perm结构成员 若要查看详细的定义请参阅文件
  • 【二十五】springboot整合jedis和redisson布隆过滤器处理缓存穿透

    springboot篇章整体栏目 一 springboot整合swagger 超详细 二 springboot整合swagger 自定义 超详细 三 springboot整合token 超详细 四 springboot整合mybatis p
  • win10 win11下添加nfs客服端到linux

    在控制面板中找到程序和功能 点击 启动或关闭windows功能 打上这两个 然后确认 在资源管理器中添加linux中的nfs目录 点击如下位置 配置本地驱动器和服务器路径 以上配好后就可以访问linux上的资源了 但只有只读权限 解决办法如
  • SpringCloud分布式开发五大神兽

    SpringCloud分布式开发五大神兽 服务发现 Netflix Eureka 客服端负载均衡 Netflix Ribbon 断路器 Netflix Hystrix 服务网关 Netflix Zuul 分布式配置 Spring Cloud
  • js基础学习第一天(关于DOM和BOM)一

    关于BOM和DOM BOM 下面一幅图很好的说明了BOM和DOM的关系 BOM提供了一些访问窗口对象的一些方法 我们可以用它来移动窗口位置 改变窗口大小 打开新窗口和关闭窗口 弹出对话框 进行导航以及获取客户的一些信息如 浏览器品牌版本 屏
  • pikache靶场通关——XSS漏洞

    文章目录 前言 环境 第一关 反射型xss get Step 1 输入特殊字符测试 Step 2 输入js语句 Step 3 在URL中输入js语句 第二关 反射性xss post Step 1 输入获取cookie的js语句 第三关 存储
  • 终于有人把Java内存模型(JMM)说清楚了

    网上有很多关于Java内存模型的文章 在 深入理解Java虚拟机 和 Java并发编程的艺术 等书中也都有关于这个知识点的介绍 但是 很多人读完之后还是搞不清楚 甚至有的人说自己更懵了 本文 就来整体的介绍一下Java内存模型 目的很简单
  • case when 失效,看了这篇文章就明白了

    前几天 小明在工作中写sql的时候使用到了case when 发现case when是一个工作中比较常用但是又比较绕的函数 今天特意来给大家分享一下case when 的使用的方法 关于case when的使用情况 总结下来有三种 等值转换
  • elasticsearch_script_01

    文章目录 1 script 简述 1 script的类型和作用 2 script使用的方式 2 script的使用场景 1 update scripts 2 search 和agg 中使用script 3 search中获取doc的打分数据