YYDU 2016-12-29
基于上一篇博文基础上,进行es的操作,document的新增比较简单,就不说了,这里主要说说更新操作。
更新操作,有两大类,一个是Replace,一个是Update,就是说一个是替换,一个是更新。 替换,就是全文档更换,而更新可以只针对文档的局部字段。
1. 这里先说简单的Replace的操作。
先创建一个document,索引名为gengxin,文档类型为replace。
1 [water@CloudGame ES]$ curl -XPUT 'localhost:9200/gengxin/replace/1?pretty' -d '
2 {
3 "name": "shihuc",
4 "job": "System Software Dev Manager",
5 "date": "2016-10-19"
6 }'
7 {
8 "_index" : "gengxin",
9 "_type" : "replace",
10 "_id" : "1",
11 "_version" : 1,
12 "_shards" : {
13 "total" : 2,
14 "successful" : 1,
15 "failed" : 0
16 },
17 "created" : true #注意,这里的信息状态是true
18 }查询看看创建的结果:
1 [water@CloudGame ES]$ curl "localhost:9200/gengxin/replace/1?pretty"
2 {
3 "_index" : "gengxin",
4 "_type" : "replace",
5 "_id" : "1",
6 "_version" : 1,
7 "found" : true,
8 "_source" : {
9 "name" : "shihuc",
10 "job" : "System Software Dev Manager",
11 "date" : "2016-10-19"
12 }
13 }没有什么问题。 然后我们对这个id为1的document进行replace操作:
1 [water@CloudGame ES]$ curl -XPUT 'localhost:9200/gengxin/replace/1?pretty' -d '
2 {
3 "name": "wdn",
4 "job": "TK CEO"
5 }'
6 {
7 "_index" : "gengxin",
8 "_type" : "replace",
9 "_id" : "1",
10 "_version" : 2,
11 "_shards" : {
12 "total" : 2,
13 "successful" : 1,
14 "failed" : 0
15 },
16 "created" : false #注意,这里的状态是false哟,表示没有新建一个
17 }再查看一下,这个被replace了的document内容:
1 [water@CloudGame ES]$ curl "localhost:9200/gengxin/replace/1?pretty"
2 {
3 "_index" : "gengxin",
4 "_type" : "replace",
5 "_id" : "1",
6 "_version" : 2,
7 "found" : true,
8 "_source" : {
9 "name" : "wdn",
10 "job" : "TK CEO"
11 }
12 }发现没有,这个被Replace后的数据,与新建的时候字段数量都不一样了,就和一个新建很类似。内容完全被替换了。
2. 下面看看Update更新操作,其实,这个操作是针对已经建立的document修改field的内容,字段field的名字和数量是不能被修改的,是不是差别出来了???对的,就是这个差别。
1 [water@CloudGame ES]$ curl -XPUT 'localhost:9200/gengxin/update/1?pretty' -d '
2 {
3 "name": "water",
4 "job": "跑龙套的宝宝",
5 "date": "2016-10-19"
6 }'
7 {
8 "_index" : "gengxin",
9 "_type" : "update",
10 "_id" : "1",
11 "_version" : 1,
12 "_shards" : {
13 "total" : 2,
14 "successful" : 1,
15 "failed" : 0
16 },
17 "created" : true
18 }查看返回值:
1 [water@CloudGame ES]$ curl "localhost:9200/gengxin/update/1?pretty"
2 {
3 "_index" : "gengxin",
4 "_type" : "update",
5 "_id" : "1",
6 "_version" : 1,
7 "found" : true,
8 "_source" : {
9 "name" : "water",
10 "job" : "跑龙套的宝宝",
11 "date" : "2016-10-19"
12 }
13 }再来看看Update的操作:
1 [water@CloudGame ES]$ curl -XPOST "localhost:9200/gengxin/update/1/_update?pretty" -d '
2 {
3 "doc": {"job": "奋斗者"}
4 }'
5 {
6 "_index" : "gengxin",
7 "_type" : "update",
8 "_id" : "1",
9 "_version" : 5,
10 "_shards" : {
11 "total" : 2,
12 "successful" : 1,
13 "failed" : 0
14 }
15 }查看Update的结果:
1 [water@CloudGame ES]$ curl "localhost:9200/gengxin/update/1?pretty"
2 {
3 "_index" : "gengxin",
4 "_type" : "update",
5 "_id" : "1",
6 "_version" : 5,
7 "found" : true,
8 "_source" : {
9 "name" : "water",
10 "job" : "奋斗者",
11 "date" : "2016-10-19"
12 }
13 }到此,是不是发现Replace操作和Update操作的不同了?
1. 指令不同,replace前后都是PUT指令,其实,用POST也可以实现replace,比如上面的replace操作的时候,将PUT换成POST也可以的。但是最好还是用PUT, http指令中POST是用来更新数据的,PUT是用来新增数据用的,虽然两个没有严格的限制。还有,在做Update操作时,指令中含有关键字_update.
2. replace操作时,指令的-d的内容就是最后的数据的内容,也就是查询结果中_source中的内容,但是Update的操作,修改的只是_source中的某些字段的内容。
另外,补充一下Update的操作,其实除了通过doc来修改指定的字段内容,还可以通过script来实现字段内容的修改。script的东西就比较多了,这里简单的演示一个inline的脚本处理,作为引子简单介绍下!
A. 创建一个文档,并查看结果, 文档的内容是说wangbaoqiang有几顶绿帽子,开始创建的时候写的是2个,后来发现其实只有马rong个jian人一个,于是乎要修改。。。
1 [water@CloudGame ES]$ curl -XPUT "localhost:9200/gengxin/update/2?pretty" -d '{
2 > "name": "wangbaoqiang",
3 > "green_hat": "2"
4 > }'
5 {
6 "_index" : "gengxin",
7 "_type" : "update",
8 "_id" : "2",
9 "_version" : 1,
10 "_shards" : {
11 "total" : 2,
12 "successful" : 1,
13 "failed" : 0
14 },
15 "created" : true
16 }
17 [water@CloudGame ES]$
18 [water@CloudGame ES]$ curl "localhost:9200/gengxin/update/2?pretty"
19 {
20 "_index" : "gengxin",
21 "_type" : "update",
22 "_id" : "2",
23 "_version" : 1,
24 "found" : true,
25 "_source" : {
26 "name" : "wangbaoqiang",
27 "green_hat" : "2"
28 }
29 }好吧,进行修改吧(行内脚本的方式实现):
1 [water@CloudGame ES]$ curl -XPOST "localhost:9200/gengxin/update/2/_update?pretty" -d '{
2 > "script": "ctx._source.green_hat = count",
3 > "inline": {
4 > "params" : {
5 > "count" : 1
6 > }
7 > }
8 > }'
9 {
10 "error" : {
11 "root_cause" : [ {
12 "type" : "remote_transport_exception",
13 "reason" : "[node-1][10.90.6.172:9300][indices:data/write/update[s]]"
14 } ],
15 "type" : "illegal_argument_exception",
16 "reason" : "failed to execute script",
17 "caused_by" : {
18 "type" : "script_exception",
19 "reason" : "scripts of type [inline], operation [update] and lang [groovy] are disabled"
20 }
21 },
22 "status" : 400
23 }报错了,意思是说行内脚本通过groovy语言执行update操作是被禁用了的。 查看帮助文档吧,发现script章节有介绍,需要修改elasticsearch.yml配置文件,再其最后,加入下面的内容,重新启动es:
1 script.inline: true 2 script.indexed: true 3 script.engine.groovy.inline.aggs: true
重启ES后,再次操作上述script方式的update指令:
1 [water@CloudGame ES]$ curl -XPOST "localhost:9200/gengxin/update/2/_update?pretty" -d '{
2 "script": "ctx._source.green_hat = count",
3 "inline": {
4 "params" : {
5 "count" : 1
6 }
7 }
8 }'
9 {
10 "_index" : "gengxin",
11 "_type" : "update",
12 "_id" : "2",
13 "_version" : 4,
14 "_shards" : {
15 "total" : 2,
16 "successful" : 1,
17 "failed" : 0
18 }
19 }
20 [water@CloudGame ES]$
21 [water@CloudGame ES]$ curl "localhost:9200/gengxin/update/2?pretty"
22 {
23 "_index" : "gengxin",
24 "_type" : "update",
25 "_id" : "2",
26 "_version" : 4,
27 "found" : true,
28 "_source" : {
29 "name" : "wangbaoqiang",
30 "green_hat" : 1
31 }
32 }是不是也还不错,比较容易实现。
补充一点tip,若update操作中doc和script关键字都出现了,那么doc将被忽略!
elasticsearch中给类型增加新字段
For instance, let’s add a new field to my_index:
PUT /my_index/_mapping/my_type
{
"my_type": {
"properties": {
"english_title": {
"type": "string",
"analyzer": "english"
}
}
}
} 另外一部分,则需要先做聚类、分类处理,将聚合出的分类结果存入ES集群的聚类索引中。数据处理层的聚合结果存入ES中的指定索引,同时将每个聚合主题相关的数据存入每个document下面的某个field下。