天天看点

ElasticSearch系列(二):基本数据操作(中)

作者:paulpei

接前文【ElasticSearch系列(二):基本数据操作(上)】

6.查找文档主体信息

上面查找到并返回的信息比较多,如果,仅仅想返回需要的_source部分,主体信息。

需要执行如下命令:GET ddz/_source/1

则返回信息如下:

{

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

7.自动文档 ID 生成

文档的ID可以视情况而指定具体值,也可以由ES自动生成,但是自动生成的话,需要使用POST,而不是 PUT。

例如:

POST my_ddz/_doc/

{

"uid":10001,

"nickname":"麦子",

"coin":3000,

"phone":13622445609,

"score":203

}

执行,返回如下:

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "GbfZw4YBGAbwf5pv8YVW",

"_version" : 1,

"result" : "created",

"_shards" : {

"total" : 2,

"successful" : 1,

"failed" : 0

},

"_seq_no" : 0,

"_primary_term" : 1

}

从上面可以看到,id会自动被分配。

注意:再次执行上面的脚本,则会再次执行插入成功,只是被分配了一个新的id。所以,此种情况下,需要特别注意数据的重复,是否超出预期。

假如,上述脚本共执行了五次,通过接口_search查看一下所有的数据的表现:

执行:GET my_ddz/_search

返回如下信息:

{

"took" : 624,

"timed_out" : false,

"_shards" : {

"total" : 1,

"successful" : 1,

"skipped" : 0,

"failed" : 0

},

"hits" : {

"total" : {

"value" : 5,

"relation" : "eq"

},

"max_score" : 1.0,

"hits" : [

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "GbfZw4YBGAbwf5pv8YVW",

"_score" : 1.0,

"_source" : {

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

},

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "Grfaw4YBGAbwf5pvjIWn",

"_score" : 1.0,

"_source" : {

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

},

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "G7faw4YBGAbwf5pvr4Wp",

"_score" : 1.0,

"_source" : {

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

},

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "HLfaw4YBGAbwf5pvtoUj",

"_score" : 1.0,

"_source" : {

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

},

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "Hbfpw4YBGAbwf5pvJIXt",

"_score" : 1.0,

"_source" : {

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

}

]

}

}

8.获取自动生成id的文档的_source的信息

对于,自动生成id的文档,如果也想获取_source的信息

执行如下脚本:GET my_ddz/_source/GbfZw4YBGAbwf5pv8YVW

返回信息如下:

{

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

注意:id 无需加 ” ”

9.获取_source的部分字段信息

如果仅仅想获取_source的部分字段,则执行如下脚本:

GET my_ddz/_source/GbfZw4YBGAbwf5pv8YVW?_source=nickname,coin

返回信息如下:

{

"nickname" : "麦子",

"coin" : 3000

}

GET my_ddz/_source/GbfZw4YBGAbwf5pv8YVW?_source=uid,coin

返回信息如下:

{

"uid" : 10001,

"coin" : 3000

}

10.获取多个文档的信息

如果想获取多个文档的信息,执行如下命令:

GET _mget

{

"docs": [

{

"_index": "my_ddz",

"_id": "GbfZw4YBGAbwf5pv8YVW"

},

{

"_index": "my_ddz",

"_id": "Hbfpw4YBGAbwf5pvJIXt"

}

]

}

或者:

GET my_ddz/_mget

{

"ids": [

"GbfZw4YBGAbwf5pv8YVW",

"Hbfpw4YBGAbwf5pvJIXt"

]

}

返回信息如下:

{

"docs" : [

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "GbfZw4YBGAbwf5pv8YVW",

"_version" : 1,

"_seq_no" : 0,

"_primary_term" : 1,

"found" : true,

"_source" : {

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

},

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "Hbfpw4YBGAbwf5pvJIXt",

"_version" : 1,

"_seq_no" : 4,

"_primary_term" : 1,

"found" : true,

"_source" : {

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

}

]

}

如果_id为数字,则可以使用引号,也可以不使用引号:

如下:

GET ddz/_mget

{

"ids": [

1, # 未使用引号

2

]

}

或者

GET ddz/_mget

{

"ids": [

"1", # 使用引号

"2"

]

}

11.获得多个文档的_source的部分字段信息

如果想获得多个文档的_source的部分字段信息,如下:

GET my_ddz/_mget/?_source=uid,coin

{

"ids":

[

"GbfZw4YBGAbwf5pv8YVW",

"Hbfpw4YBGAbwf5pvJIXt"

]

}

或者

GET _mget

{

"docs": [

{

"_index": "my_ddz",

"_id": "GbfZw4YBGAbwf5pv8YVW",

"_source": [

"uid",

"coin"

]

},

{

"_index": "my_ddz",

"_id": "Hbfpw4YBGAbwf5pvJIXt",

"_source": [

"uid",

"coin"

]

}

]

}

注意:上面的两个文档,可以返回不同的_source的字段信息:

例如:

GET _mget

{

"docs": [

{

"_index": "my_ddz",

"_id": "GbfZw4YBGAbwf5pv8YVW",

"_source": [

"uid",

"nickname",

"coin"

]

},

{

"_index": "my_ddz",

"_id": "Hbfpw4YBGAbwf5pvJIXt",

"_source": [

"uid",

"coin"

]

}

]

}

返回信息如下:

{

"docs" : [

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "GbfZw4YBGAbwf5pv8YVW",

"_version" : 1,

"_seq_no" : 0,

"_primary_term" : 1,

"found" : true,

"_source" : {

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000

}

},

{

"_index" : "my_ddz",

"_type" : "_doc",

"_id" : "Hbfpw4YBGAbwf5pvJIXt",

"_version" : 1,

"_seq_no" : 4,

"_primary_term" : 1,

"found" : true,

"_source" : {

"uid" : 10001,

"coin" : 3000

}

}

]

}

三.修改文档

修改一个文档时,通常会使用 PUT 来进行操作,并且,需要指定一个特定的 id 。

在修改之前,我们先查看一下原来的文档内容是什么:

GET ddz/_source/1

返回如下:

{

"uid" : 10001,

"nickname" : "麦子",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

假设需要将 "nickname" : "麦子" 修改为 "nickname" : "水稻" ,执行如下:

  1. 更新所有字段

PUT ddz/_doc/1

{

"uid" : 10001,

"nickname" : "水稻",

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

返回信息如下:

{

"_index" : "ddz",

"_type" : "_doc",

"_id" : "1",

"_version" : 6,

"result" : "updated", # 修改操作

"_shards" : {

"total" : 2,

"successful" : 1, # 修改成功

"failed" : 0

},

"_seq_no" : 8,

"_primary_term" : 3

}

再次查看,进行验证:

GET ddz/_source/1

{

"uid" : 10001,

"nickname" : "水稻", # 修改成功

"coin" : 3000,

"phone" : 13622445609,

"score" : 203

}

上述方法,需要将文档的所有字段都列出来,有些不便。如果漏写或者写错,会导致文档与预期的不一致。

假如,我们仅执行下面命令:

PUT ddz/_doc/1

{

"nickname" : "水稻"

}

再次查看,会发现,文档仅有nickname字段了。

GET ddz/_source/1

返回如下:

{

"nickname" : "水稻"

}

2.更新特定字段

仅仅需要更新某一个字段内容时,需要调用_update 接口:

POST ddz/_update/1

{

"doc": {

"nickname": "水稻"

}

}

3.使用script 更新特定字段

也可以使用script方法来更新:

POST ddz/_update/1

{

"script": {

"source": "ctx._source.coin = params.coin;ctx._source.score = params.score;",

"lang": "painless",

"params": {

"coin": "660",

"score": "60"

}

}

}

4.查找更新字段

上述例子都是在确定文档id的情况下,对字段值做更新。而在做类似数据库SQL查找并更新字段内容操作时,需要用到接口_update_by_query,执行如下类似命令:

POST ddz/_update_by_query

{

"query": {

"match": {

"nickname": "水稻"

}

},

"script": {

"source": "ctx._source.coin = params.coin;ctx._source.score = params.score;",

"lang": "painless",

"params": {

"coin": "600",

"score": "50"

}

}

}

再次查看,会发现,找到的文档的字段coin 和score已经更新为新值了。

GET ddz/_source/1

返回如下:

{

"uid" : 10001,

"score" : "50", # 原值为:203

"phone" : 13622445609,

"nickname" : "水稻",

"coin" : "600" # 原值为:3000

}

5.中文字段的更新

注意:如果字段名字为中文,需要使用一个中括号并 escape 引号的方式来操作。

例如下存在文档:

GET ddz/_source/10

{

"uid" : 10010,

"nickname" : "玉米",

"金币" : 100,

"phone" : 13122445609,

"总分" : 20

}

更新命令类似如下:

POST ddz/_update_by_query

{

"query": {

"match": {

"nickname": "玉米"

}

},

"script": {

"source": "ctx._source[\"金币\"] = params[\"金币\"];ctx._source[\"总分\"] = params[\"总分\"];",

"lang": "painless",

"params": {

"金币": "190",

"总分": "150"

}

}

}

更新后为:

{

"总分" : "150",

"uid" : 10010,

"金币" : "190",

"phone" : 13122445609,

"nickname" : "玉米"

}

6.可新建文档的更新

如果指定的文档不存在,需要插入,而找到文档,则需要更新字段内容时,需要使用 upsert 属性来实现,执行如下类似命令:

POST ddz/_update/13

{

"script": {

"source": "ctx._source.score = params.score;ctx._source.coin = params.coin;",

"lang": "painless",

"params": {

"score" : 120, # 文档存在,仅仅更新的字段及其新值

"coin" : 6200 # 文档存在,仅仅更新的字段及其新值

}},

"upsert": { # 文档不存在,插入如下的新的文档字段内容

"uid" : 10013,

"score" : 102,

"phone" : 13134675609,

"nickname" : "小夏",

"coin" : 7200

}

}

后续见【ElasticSearch系列(二):基本数据操作(下)】

继续阅读