ES5_4Painless

内置脚本语言。

什么时候可以使用Painless

  • 更新或删除字段;
  • 处理数据聚合;
  • Script Field:对返回的字段提前进行计算
  • Function Score:对文档的算分进行处理
  • Ingest Pipeline中执行脚本
  • Reindex
  • Update by Query

使用Painless脚本访问字段

在不同上下文中Painless获取文档字段的语法也有所不同

  • Ingestion中
    ctx.field_name
  • Update
    ctx._source.field_name
  • Search & Aggregation
    doc["field_name"]

在Ingest Pipeline中使用Painless

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description": "to split blog tags",
"processors": [
{
"split": {
"field": "tags",
"separator": ","
}
},
{
"script": {
"source": """
if(ctx.containsKey("content")){
ctx.content_length = ctx.content.length();
}else{
ctx.content_length=0;
}
"""
}
},
{
"set": {
"field": "views",
"value": 0
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"title": "Introducing big data......",
"tags": "hadoop,elasticsearch,spark",
"content": "You konw, for big data"
}
},
{
"_index": "index",
"_id": "idxx",
"_source": {
"title": "Introducing cloud computering",
"tags": "openstack,k8s",
"content": "You konw, for cloud"
}
}
]
}

上面的命令中增加了一个类型为script的processor:

  • 如果存在content字段,则计算字段长度,并增加一个长度字段
  • 否则默认取长度为0

在更新文档时使用Painless

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PUT tech_blogs/_doc/1
{
"title":"Introducing big data......",
"tags":"hadoop,elasticsearch,spark",
"content":"You konw, for big data",
"views":0
}

POST tech_blogs/_update/1
{
"script": {
"source": "ctx._source.views += params.new_views",
"params": {
"new_views":100
}
}
}

上面脚本根据参数new_views来更新原文档的views字段。
这样做的好处主要是保证文档更新的原子性。

也可以将script保存在Cluster State里,通过id引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST _scripts/update_views
{
"script":{
"lang": "painless",
"source": "ctx._source.views += params.new_views"
}
}

POST tech_blogs/_update/1
{
"script": {
"id": "update_views",
"params": {
"new_views":1000
}
}
}

在查询中使用Painless

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GET tech_blogs/_search
{
"script_fields": {
"rnd_views": {
"script": {
"lang": "painless",
"source": """
java.util.Random rnd = new Random();
doc['views'].value+rnd.nextInt(1000);
"""
}
}
},
"query": {
"match_all": {}
}
}

修改查询结果,给views字段加上一个随机值。