文章目录

  • 1. script 简述
    • 1. script的类型和作用
    • 2. script使用的方式
  • 2. script的使用场景
    • 1. update scripts
    • 2. search 和agg 中使用script
    • 3. search中获取doc的打分数据
  • 3. script灵活使用的一些理解
  • 4. script的使用方式
  • 5. 样例
    • 1. 在search中使用 script_score功能
    • 2. 获取field的value,通过doc values
    • 3. 获取field value 通过_source字段
    • 4. 获取field value 通过store field

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会更好。

elasticsearch_script_01相关推荐

最新文章

  1. PE文件和COFF文件格式分析——导出表的应用——通过导出表隐性加载DLL
  2. 为MyEclipse加入自己定义凝视
  3. java moment 日期转换_关于日期:如何使用Java 8 DateTime API转换修改后的儒略日数字...
  4. 约瑟夫问题的循环链表实现
  5. 记录爬取信用中国,里面的行政许可内容,行政处罚,守信激励的内容,并以excel形式显示
  6. 微服务和其他常见架构
  7. fanuc roboguide_FANUC机器人虚拟仿真教程:Roboguide弧焊仿真工作站工装添加
  8. Windows Phone Local Database Schema Upgrade Part1 - Adding new columns
  9. 求H21时的仿射变换要参考当前坐标系
  10. 程序员为什么热衷造轮子?
  11. ADT下载地址(含各版本),最新ADT-23.0.7
  12. android 字体设置为中等粗细
  13. 数值积分——梯形公式和Simpson公式
  14. 蓝牙资讯|Q2全球TWS耳机出货量排行出炉,蓝牙音频新技术将推出市场
  15. python在excel应用实例视频-超简单:用Python让Excel飞起
  16. 线性代数笔记(矩阵)
  17. Advanced IP Scanner教程 详细使用方法
  18. 宝石塔防的贴吧地址:
  19. RISC-V 实现整数运算指令(Part 2)
  20. 非线性方程的数值解法

热门文章

  1. 趣谈设计模式 | 工厂模式(Factory):利用工厂来创建对象
  2. frida hook so层方法大全
  3. Python获取.wav音频的时长
  4. 如果我问你:排序算法的「稳定性」有何意义?你怎么回答?
  5. 李超:WebRTC传输与服务质量
  6. Nebula:Slack 的覆盖全球性的开源网络
  7. 符乐安:2020年短视频创作将迎来新的高峰
  8. 2019 VOD编码工具指南
  9. 进程组 会话 作业
  10. SuperSQL:跨数据源、跨DC、跨执行引擎的高性能大数据SQL中间件