天天看點

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系列(二):基本資料操作(下)】

繼續閱讀