elasticsearch_script_01
文章目录
- 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的类型有三种,就像是三种编程语言一样
- painless: 这个是最推荐的一种方式
- expression: lucene expression
- mustache: 这个一般用来定义search_template使用
- 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前缀获取到
- ctx._source : doc的_source 字段
- ctx.op : 当前操作,index/delete/noop
- ctx._index 等: doc的meta-fields,有些是只读的
2. search 和agg 中使用script
script fields 会在每个搜索命中的doc执行一次,其他在search和agg中使用的脚本将针对可能与search或agg匹配的每个文档执行一次,所有的普通字段值可以通过下面方式获取
- doc-values : 获取方式为doc[‘cost_price’].value,只有有doc_value的字段才可以这样使用,text字段理论上不能这样用
- the _source field : params._source.first_name 这里的params前缀必须要有
- 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一样
常见的数据类型有
- 字符串:对应的方法有.length() 方法
- 数组[]: 对应的属性有.length 对应的方法有.add() .size() 可以试试看看对应于field的value是不是可以添加元素,可能是根据现有field value的类型来决定的
- 正则:/aa/.split(str) 这个也太复杂了,就是java正则的使用,感觉一般情况先应该用不上吧。
- 数字
script的逻辑表达式只有两种
- if else
- 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的使用方式
- 直接在某些query中使用
script
关键字 - search中使用script来产生额外的field使用的
script_field
关键字,然后再嵌套使用script
关键字 - search的
function_score
中使用script来自定义score时候使用的script_score
关键字,然后再嵌套使用script
关键字 - 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相关推荐
最新文章
- PE文件和COFF文件格式分析——导出表的应用——通过导出表隐性加载DLL
- 为MyEclipse加入自己定义凝视
- java moment 日期转换_关于日期:如何使用Java 8 DateTime API转换修改后的儒略日数字...
- 约瑟夫问题的循环链表实现
- 记录爬取信用中国,里面的行政许可内容,行政处罚,守信激励的内容,并以excel形式显示
- 微服务和其他常见架构
- fanuc roboguide_FANUC机器人虚拟仿真教程:Roboguide弧焊仿真工作站工装添加
- Windows Phone Local Database Schema Upgrade Part1 - Adding new columns
- 求H21时的仿射变换要参考当前坐标系
- 程序员为什么热衷造轮子?
- ADT下载地址(含各版本),最新ADT-23.0.7
- android 字体设置为中等粗细
- 数值积分——梯形公式和Simpson公式
- 蓝牙资讯|Q2全球TWS耳机出货量排行出炉,蓝牙音频新技术将推出市场
- python在excel应用实例视频-超简单:用Python让Excel飞起
- 线性代数笔记(矩阵)
- Advanced IP Scanner教程 详细使用方法
- 宝石塔防的贴吧地址:
- RISC-V 实现整数运算指令(Part 2)
- 非线性方程的数值解法