摘要:Elasticsearch
《Elasticsearch搜索引擎構(gòu)建入門(mén)與實(shí)戰(zhàn)》第三章讀書(shū)筆記
索引操作
索引操作主要有創(chuàng)建,刪除,關(guān)閉,打開(kāi),別名等
(1)創(chuàng)建索引
請(qǐng)求類型為PUT,語(yǔ)法為
PUT /${index_name}
{
"settings": {
...
},
"mappings": {
...
}
}
其中settings中設(shè)置索引的配置項(xiàng),比如主分片數(shù)和副分片數(shù),mappings填寫(xiě)數(shù)據(jù)組織結(jié)構(gòu),例如如下語(yǔ)句創(chuàng)建了主分片3,副分片1,兩個(gè)字段的索引
PUT /my_label
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"ent_name": {
"type": "keyword"
},
"score": {
"type": "double"
}
}
}
}
查看kibana的Index Management,已經(jīng)顯示了primaries=3,replicas=1

(2)創(chuàng)建索引
刪除索引,使用DELETE請(qǐng)求
DELETE /my_index
(3)關(guān)閉索引
關(guān)閉索引之后ES索引只負(fù)責(zé)數(shù)據(jù)存儲(chǔ),不能提供數(shù)據(jù)更新和搜索功能,知道索引再次打開(kāi),使用POST請(qǐng)求,_close路由
POST /my_label/_close
(4)打開(kāi)索引
同理POST請(qǐng)求_open路由
POST /my_label/_open
(5)索引別名
可以給一個(gè)或者多個(gè)es索引定義一個(gè)另一個(gè)名稱,相當(dāng)于linux的用戶名和用戶組名,這樣就可以實(shí)現(xiàn)對(duì)多個(gè)索引進(jìn)行查詢(用戶組),而不是一個(gè)一個(gè)查詢索引(用戶),關(guān)系如下

舉例先創(chuàng)建3個(gè)索引,最后三個(gè)都別名為同一個(gè)索引
PUT /my_index_1
{
"mappings": {
"properties": {
"title":{
"type": "text"
},
"city":{
"type": "keyword"
},
"price": {
"type": "double"
}
}
}
}
PUT /my_index_2
{
"mappings": {
"properties": {
"title":{
"type": "text"
},
"city":{
"type": "keyword"
},
"price": {
"type": "double"
}
}
}
}
PUT /my_index_3
{
"mappings": {
"properties": {
"title":{
"type": "text"
},
"city":{
"type": "keyword"
},
"price": {
"type": "double"
}
}
}
}
再插入三條數(shù)據(jù)
POST /my_index_1/_doc/001
{
"title":"好再來(lái)餐廳",
"city": "青島",
"price": 578.23
}
POST /my_index_3/_doc_/001
{
"title":"好再來(lái)網(wǎng)吧",
"city": "青島",
"price": 578.23
}
POST /my_index_2/_doc_/001
{
"title":"好再來(lái)浴室",
"city": "青島",
"price": 578.23
}
將my_index,my_index_2,my_index_3三個(gè)索引都別名為my_index_all
POST /_aliases
{
"actions": [
{
"add": {
"index": "my_index_1",
"alias": "my_index_all"
}
},
{
"add": {
"index": "my_index_2",
"alias": "my_index_all"
}
},
{
"add": {
"index": "my_index_3",
"alias": "my_index_all"
}
}
]
}
此時(shí)對(duì)別名之后的索引集合做搜索,所有id是001的文檔
GET /my_index_all/_doc/001
報(bào)錯(cuò)和多個(gè)索引相關(guān),無(wú)法定位
{
"error" : {
"root_cause" : [
{
"type" : "illegal_argument_exception",
"reason" : "alias [my_index_all] has more than one index associated with it [my_index_2, my_index_3, my_index_1], can't execute a single index op"
}
],
"type" : "illegal_argument_exception",
"reason" : "alias [my_index_all] has more than one index associated with it [my_index_2, my_index_3, my_index_1], can't execute a single index op"
},
"status" : 400
}
可以進(jìn)行其他條件查詢
POST /my_index_all/_search
{
"query":{
"match":{
"title": "好再"
}
}
}
返回三條結(jié)果,每一條文檔給出了所在的索引(_index)
{
"took" : 9,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "my_index_1",
"_id" : "001",
"_score" : 0.5753642,
"_source" : {
"title" : "好再來(lái)餐廳",
"city" : "青島",
"price" : 578.23
}
},
{
"_index" : "my_index_2",
"_id" : "001",
"_score" : 0.5753642,
"_source" : {
"title" : "好再來(lái)浴室",
"city" : "青島",
"price" : 578.23
}
},
{
"_index" : "my_index_3",
"_id" : "001",
"_score" : 0.5753642,
"_source" : {
"title" : "好再來(lái)網(wǎng)吧",
"city" : "青島",
"price" : 578.23
}
}
]
}
}
如果要?jiǎng)h除別名使用如下語(yǔ)法
POST /_aliases
{
"actions":[
{ "remove":{"index": "my_index_1", "alias": "my_index_all"}},
{ "remove":{"index": "my_index_2", "alias": "my_index_all"}},
{ "remove":{"index": "my_index_3", "alias": "my_index_all"}}
]
}
映射操作
映射類似于傳統(tǒng)數(shù)據(jù)庫(kù)的表結(jié)構(gòu),ES可以自動(dòng)推斷數(shù)據(jù)類型,建議用戶手動(dòng)創(chuàng)建。
(1)創(chuàng)建映射
創(chuàng)建映射的基本語(yǔ)法如下,在創(chuàng)建索引的時(shí)候直接創(chuàng)建
PUT /${index_name}
{
"mappings": {
"properties": {
"cols1": {"type": ""}
}
}
}
也可以先創(chuàng)建索引,再創(chuàng)建mappings,使用POST請(qǐng)求傳給_mapping路由
PUT /my_index_4
POST /my_index_4/_mapping
{
"properties": {
"title": {"type": "text"},
"city": {"type": "keyword"},
"price": {"type": "double"}
}
}
(2)查看映射
查看映射直接使用GET和路由
GET /my_index_4/_mapping
(3)拓展映射
映射中已經(jīng)定義的字段的屬性或者類型是不能修改,這能增加字段,增加字段的DSL是一樣的,使用POST請(qǐng)求_mapping路由
POST /my_index_4/_mapping
{
"properties": {
"degree": {"type": "keyword"}
}
}
(3)基本的數(shù)據(jù)類型
1.keyword類型
keyword代表不進(jìn)行切分的字符串類型,在構(gòu)建索引時(shí),ES直接對(duì)keyword的字符串做倒排索引,而不是對(duì)切分之后的子部分都做倒排索引。keyword一般用于字符串比較相等,用于過(guò)濾,排序,聚合的場(chǎng)景,在DSL中使用term查詢
例如查詢某個(gè)字段為某個(gè)值進(jìn)行過(guò)濾
GET /my_index_4/_search
{
"query":{
"term": {
"city": {"value": "揚(yáng)州"}
}
}
}
如果對(duì)keyword字段用match進(jìn)行部分內(nèi)容的全文檢索是不會(huì)命中文檔的,例如
GET /my_index_4/_search
{
"query":{
"match": {
"city": "州"
}
}
}
2.text類型
text類型是對(duì)于字符串進(jìn)行切割,切割的每一部分加入倒排索引中,搜索匹配的時(shí)候會(huì)進(jìn)行打分
GET /my_label/_search
{
"query": {
"match": {
"title": "好來(lái)藥酒"
}
}
}
返回結(jié)果按照score進(jìn)行降序
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0577903,
"hits" : [
{
"_index" : "my_label",
"_id" : "003",
"_score" : 1.0577903,
"_source" : {
"title" : "好再來(lái)藥店",
"city" : "青島",
"price" : 578.23
}
},
{
"_index" : "my_label",
"_id" : "001",
"_score" : 0.8630463,
"_source" : {
"title" : "好再來(lái)酒店",
"city" : "青島",
"price" : 578.23
}
},
{
"_index" : "my_label",
"_id" : "002",
"_score" : 0.36464313,
"_source" : {
"title" : "好再來(lái)飯店",
"city" : "青島",
"price" : 578.23
}
}
]
}
}
如果對(duì)text字段使用term搜索會(huì)搜索不到,因?yàn)閠ext已經(jīng)被切割了
POST /my_label/_search
{
"query": {
"match": {
"title": {"value": "好再來(lái)飯店" }
}
}
}
返回空文檔,分?jǐn)?shù)為null
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
如果text類型在mapping里手指了參數(shù):index:false,則該字段無(wú)法被索引到,只能用來(lái)展示,無(wú)法用來(lái)匹配搜索
PUT /hotel/_doc/_mapping
{
"properties": {
"no_index_col": {"type": "text", "index": false}
}
}
搜索該字段會(huì)報(bào)錯(cuò)沒(méi)有被索引,同樣給keyword字段設(shè)置該屬性也無(wú)法檢索
"reason": "Cannot search on field [no_index_col] since it is not indexed
3.數(shù)值類型
ES支持多種數(shù)值類型(long,integer,short,byte,double,float等),應(yīng)該在滿足業(yè)務(wù)需求的情況下盡量算則范圍小的數(shù)值類型。舉例
PUT /my_index_5
{
"mappings":{
"properties": {
"name": {"type": "keyword"},
"age": {"type": "integer"},
"score": {"type": "double"},
"no": {"type": "long"}
}
}
}
插入幾條數(shù)據(jù)
POST /my_index_5/_doc/001
{
"name": "xiaogp",
"age":13,
"score": 98.5,
"no": 123456789
}
POST /my_index_5/_doc/002
{
"name": "wangfan",
"age":92,
"score": 33.5,
"no": 123456786
}
POST /my_index_5/_doc/003
{
"name": "xuguangfeng",
"age":33,
"score": 71.5,
"no": 123456788
}
數(shù)值類型主要用于term搜索和范圍搜索range,例如查找score在60-100之間的文檔
POST /my_index_5/_search
{
"query": {
"range": {
"score": {
"gt": 60,
"lt": 100
}
}
}
}
結(jié)果返回兩條文檔
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index_5",
"_id" : "001",
"_score" : 1.0,
"_source" : {
"name" : "xiaogp",
"age" : 13,
"score" : 98.5,
"no" : 123456789
}
},
{
"_index" : "my_index_5",
"_id" : "003",
"_score" : 1.0,
"_source" : {
"name" : "xuguangfeng",
"age" : 33,
"score" : 71.5,
"no" : 123456788
}
}
]
}
}
4.布爾類型
布爾類型在mapping中使用boolean定義,搜索時(shí)使用term精確匹配,匹配值可以直接是true,false,也可以是字符串格式的true,false
# 給my_index_5新增一個(gè)字段
POST /my_index_5/_mapping
{
"properties": {
"is_good": {"type": "boolean"}
}
}
給my_index_5中001文檔增加新字段的數(shù)據(jù)
POST /my_index_5/_doc/001
{
"name": "xiaogp",
"age":13,
"score": 98.5,
"no": 123456789,
"is_good": "true"
}
搜索boolean字段
GET /my_index_5/_search
{
"query": {
"term": {
"is_good": {"value": "true"} # 可以不帶雙引號(hào)
}
}
}
5.日期類型
在ES中時(shí)間日期類型是date,默認(rèn)支持的類型中不包含yyyy-MM-dd HH:mm:ss,需要在設(shè)置映射時(shí)增加format屬性
PUT /my_label
{
"mappings": {
"properties": {
"ent_name": {"type": "keyword"},
"update_date": {"type": "date"},
"score": {"type": "double"}
}
}
}
插入yyyy-MM-dd數(shù)據(jù)成功
POST /my_label/_doc/001
{
"ent_name": "xiaogp",
"score": 23.3,
"update_date": "2021-01-01"
}
插入yyyyMMdd數(shù)據(jù)成功
POST /my_label/_doc/002
{
"ent_name": "xiaogp",
"score": 23.3,
"update_date": "20210109"
}
看一下插入的數(shù)據(jù),雖然這兩種格式不一樣,但是都是ES的date默認(rèn)支持的格式,因此都成功寫(xiě)入了,且展示的格式不一樣
{
"_index" : "my_label",
"_type" : "_doc",
"_id" : "001",
"_score" : 1.0,
"_source" : {
"ent_name" : "xiaogp",
"score" : 23.3,
"update_date" : "2021-01-01"
}
},
{
"_index" : "my_label",
"_type" : "_doc",
"_id" : "002",
"_score" : 1.0,
"_source" : {
"ent_name" : "xiaogp",
"score" : 23.3,
"update_date" : "20210109"
}
}
再插入yyyy-MM-dd HH:mm:ss數(shù)據(jù)報(bào)錯(cuò)
POST /my_label/_doc/003
{
"ent_name": "xiaogp",
"score": 23.3,
"update_date": "2021-01-09 11:11:11"
}
報(bào)錯(cuò)信息如下顯示日期類型解析錯(cuò)誤
{
"type": "mapper_parsing_exception",
"reason": "failed to parse field [update_date] of type [date] in document with id '003'"
}
如果要插入和顯示yyyy-MM-dd HH:mm:ss數(shù)據(jù),需要求改mapping
PUT /my_label
POST /my_label/_doc/_mapping
{
"properties": {
"ent_name": {"type": "keyword"},
"update_date":
{"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"score": {"type": "double"}
}
}
再插一次顯示成功
# GET /my_label/_doc/003
{
"_index" : "my_label",
"_type" : "_doc",
"_id" : "003",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"ent_name" : "xiaogp",
"score" : 23.3,
"update_date" : "2021-01-09 11:11:11"
}
}
date類型的常用查詢是range查詢,例如查詢時(shí)間范圍的文檔
GET /my_label/_search
{
"query": {
"range": {
"update_date": {
"gte": "2021-01-01",
"lte": "2022-01-01"
}
}
}
}
返回如下
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_label",
"_type" : "_doc",
"_id" : "003",
"_score" : 1.0,
"_source" : {
"ent_name" : "xiaogp",
"score" : 33.3,
"update_date" : "2022-01-09 11:11:11"
}
}
]
}
6.數(shù)組類型
數(shù)據(jù)類型是不需要定義的,只需要定義數(shù)組元素的類型,比如定義為keyword,寫(xiě)入數(shù)據(jù)的時(shí)候使用類似于JSONArray的格式即可
# 重新創(chuàng)建一個(gè)索引,tag是數(shù)組字段,內(nèi)部元素都是keyword
PUT /my_label
POST /my_label/_doc/_mapping
{
"properties": {
"ent_name": {"type": "keyword"},
"tag": {"type": "keyword"},
"score": {"type": "double"}
}
}
插入一條數(shù)據(jù),DSL中tag字段使用JSONArray格式
POST /my_label/_doc/001
{
"ent_name": "xiaogp",
"score": 23.3,
"tag": ["好人", "有錢", "有才"]
}
GET /my_label/_doc/001
數(shù)據(jù)返回如下
{
"_index" : "my_label",
"_type" : "_doc",
"_id" : "001",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"ent_name" : "xiaogp",
"score" : 23.3,
"tag" : [
"好人",
"有錢",
"有才"
]
}
}
如果插入的數(shù)據(jù)是JSONArray,保存的時(shí)候想采用String的格式,則需要轉(zhuǎn)義,使用三引號(hào)插入
POST /my_label/_doc/003
{
"ent_name": "xiaogp",
"score": 23.3,
"tag": """["好人", "有錢", "男人"]"""
}
在搜索的時(shí)候kibana也會(huì)顯示出三引號(hào)
# GET /my_label/_doc/003
{
"_index" : "my_label",
"_type" : "_doc",
"_id" : "003",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"ent_name" : "xiaogp",
"score" : 23.3,
"tag" : """["好人", "有錢", "男人"]"""
}
}
用Python客戶端驗(yàn)證一下使用三引號(hào)和不使用直接插入Array在讀取數(shù)據(jù)時(shí)是否能夠區(qū)分
>>> from elasticsearch import Elasticsearch
>>> es = Elasticsearch(hosts="192.168.61.240", port=8200, timeout=200)
>>> es.get(index="my_label", doc_type="_doc", id='001')['_source']['tag']
['好人', '有錢', '有才']
>>> es.get(index="my_label", doc_type="_doc", id='003')['_source']['tag']
'["好人", "有錢", "男人"]'
可以看到取數(shù)的時(shí)候三引號(hào)沒(méi)有了,保留了插入時(shí)候的字符串格式,如果按照數(shù)組插入,取數(shù)的時(shí)候也返回Python數(shù)組
數(shù)組查詢的時(shí)候?qū)嶋H上是對(duì)數(shù)據(jù)內(nèi)部元素做與或非查詢,最簡(jiǎn)單的查詢是搜索數(shù)組字段中包含某個(gè)keyword的文檔
GET /my_label/_search
{
"query": {
"term": {
"tag": {
"value": "有才"
}
}
}
}
使用term查詢,此時(shí)只要tag中包含‘有才;的文檔都會(huì)被返回,如果數(shù)組中有多個(gè)值需要搜索,使用terms
GET /my_label/_search
{
"query": {
"terms": {
"tag": [
"好人",
"有才"
]
}
}
}
terms傳入的對(duì)象是一個(gè)數(shù)組,只要tag中有數(shù)組中的任意一個(gè),文檔就會(huì)被返回,相當(dāng)于元素的并集or查詢,結(jié)合bool+must語(yǔ)句可以實(shí)現(xiàn)與查詢,取數(shù)據(jù)元素的交集
GET /my_label/_search
{
"query": {
"bool": {
"must": [
{"term": {
"tag": {
"value": "好人"
}
}},
{"term": {
"tag": {
"value": "有才"
}
}}
]
}
}
}
文檔操作
(1)寫(xiě)入單條文檔
寫(xiě)入文檔的請(qǐng)求類型是POST,請(qǐng)求語(yǔ)法如下
POST /${index_name}/_doc/${_id}
{
...
}
這種方式是用戶直接定義_id值,不使用es生成的id,請(qǐng)求體是JSON格式,用戶也可以不指定_id直接POST+請(qǐng)求體,此時(shí)ES將會(huì)自動(dòng)生成id
POST /${index_name}/_doc
{
...
}
例如
POST /my_label/_doc
{
"title": "123",
"city": "234",
"price": 23.3
}
GET /my_label/_search
返回結(jié)果的_id是ES自動(dòng)隨機(jī)生成的
{
"_index" : "my_label",
"_type" : "_doc",
"_id" : "YIygTn8Bxh2kjPU0z9Pg",
"_score" : 1.0,
"_source" : {
"title" : "123",
"city" : "234",
"price" : 23.3
}
}
(2)批量寫(xiě)入文檔
批量寫(xiě)入多條文檔同樣是POST請(qǐng)求,例子如下
POST /_bulk
{"index": {"_index": "my_label", "_type": "_doc", "_id": "009"}}
{"title": "123","city": "234", "price": 93.3 }
{"index": {"_index": "my_label", "_type": "_doc", "_id": "010"}}
{"title": "777","city": "567", "price": 123.3 }
{"index": {"_index": "my_label", "_type": "_doc", "_id": "011"}}
{"title": "666","city": "ftyg", "price": 31.3 }
以上一共插入了3條數(shù)據(jù),每條數(shù)據(jù)是上下兩行,第一行代表要插入的索引,_type以及_id,在新版中中_type可以不指定默認(rèn)是_doc,_id不指定隨機(jī)生成,返回如下插入成功
{
"took" : 103,
"errors" : false,
"items" : [
{
"index" : {
"_index" : "my_label",
"_type" : "_doc",
"_id" : "009",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1,
"status" : 200
}
},
{
"index" : {
"_index" : "my_label",
"_type" : "_doc",
"_id" : "010",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1,
"status" : 200
}
},
{
"index" : {
"_index" : "my_label",
"_type" : "_doc",
"_id" : "011",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1,
"status" : 200
}
}
]
}
如果數(shù)據(jù)量很大,行數(shù)很多,推薦使用linux的curl進(jìn)行批量插入,例如將以上3條數(shù)據(jù)共6行寫(xiě)入一個(gè)文件
# vim bulk_data.json
{"index": {"_index": "my_label", "_type": "_doc", "_id": "012"}}
{"title": "1233333","city": "234", "price": 93.3 }
{"index": {"_index": "my_label", "_type": "_doc", "_id": "013"}}
{"title": "777777","city": "567", "price": 123.3 }
{"index": {"_index": "my_label", "_type": "_doc", "_id": "014"}}
{"title": "66666","city": "ftyg", "price": 31.3 }
curl -H "Content-Type: application/json" -X POST '192.168.61.240:8200/_bulk?pretty' --data-binary "@bulk_data.json"
最終達(dá)到的效果是一樣的,解釋一下curl和請(qǐng)求路由中的相關(guān)參數(shù)
*-H:自定義頭信息傳遞給服務(wù)器,引號(hào)字符串
*-X:指定 HTTP 請(qǐng)求的方法,curl默認(rèn)是GET請(qǐng)求
*--data-binary:HTTP POST請(qǐng)求中的數(shù)據(jù)為純二進(jìn)制數(shù)據(jù),value如果是@file_name,則保留文件中的回車符和換行符,不做任何轉(zhuǎn)換
*pretty:讓es美化輸出,美化為JSON格式
linux控制臺(tái)會(huì)有輸出,如果不想看到輸出可以寫(xiě)入文件>或者使用curl的-o
(3)更新單條文檔
更新文檔也是POST請(qǐng)求,在請(qǐng)求路由最后增加_update即可,例如
POST /my_label/_doc/010/_update
{
"doc": {
"title" : "888"
}
}
該語(yǔ)句只會(huì)修改_id為010的文檔的title字段,其他不做修改,如果不加_update就是直接覆蓋原有的010文檔,覆蓋之后只有title字段其他全部刪除,如果對(duì)一個(gè)不存在的_id做更新會(huì)直接報(bào)錯(cuò)document_missing_exception,因此只能對(duì)現(xiàn)有文檔做更新,如果要實(shí)現(xiàn)有則更新無(wú)則插入的操作需要使用upsert
POST /my_label/_doc/099/_update
{
"doc": {
"title" : "888",
"city": "成都",
"price": 12.3
},
"upsert": {
"title" : "888",
"city": "成都",
"price": 12.3
}
}
相當(dāng)于如果文檔不存在執(zhí)行doc的更新內(nèi)容,如果已經(jīng)存在,執(zhí)行upsert的插入內(nèi)容
(4)批量更新文檔
批量更新文檔的bulk語(yǔ)句和批量插入類似,例子如下
POST /_bulk
{"update": {"_index": "my_label", "_type": "_doc", "_id": "010"}}
{"doc": {"title": "999", "city": "鄭州"}}
{"update": {"_index": "my_label", "_type": "_doc", "_id": "0123"}}
{"doc": {"title": "999", "city": "鄭州"}, "upsert": {"title": "999", "city": "鄭州"}}
更新兩條數(shù)據(jù),其中第二條沒(méi)有就是用upsert操作
(5)根據(jù)條件更新文檔
類似于關(guān)系型數(shù)據(jù)庫(kù)的update set where,es使用_update_by_query實(shí)現(xiàn),語(yǔ)法如下
POST /${index_name}/_update_by_query
{
"query": { // 條件查詢
},
"script":{ // 更新腳本
}
}
直接看一個(gè)例子
POST /my_label/_update_by_query
{
"query": {
"term": {
"city": {
"value": "鄭州"
}
}
},
"script": {
"source": "ctx._source['city']='蘇州'",
"lang": "painless"
}
}
先找到city字段等于鄭州的,全部更新為蘇州,script的語(yǔ)法使用painless,是es的默認(rèn)腳本。如果在請(qǐng)求體中不加入query,則會(huì)更新全部文檔
(6)刪除單條文檔
使用DELETE請(qǐng)求,請(qǐng)求體指定文檔_id即可
DELETE /my_label/_doc/010
(7)批量刪除文檔
批量刪除數(shù)據(jù)也需要POST請(qǐng)求和_bulk路由,例子如下
POST /_bulk
{"delete": {"_index": "my_label", "_type": "_doc", "_id": "009"}}
{"delete": {"_index": "my_label", "_type": "_doc", "_id": "012"}}
(8)根據(jù)條件刪除文檔
類似結(jié)構(gòu)型數(shù)據(jù)庫(kù)的delete from where,在es中使用_delete_by_query路由,和update_by_query不同的是,_delete_by_query只需要指定query,不需要script,因?yàn)閳?zhí)行的操作就是刪除是單一的確定的,例子如下
POST /my_label/_doc/_delete_by_query
{
"query": {
"term": {
"city": {
"value": "蘇州"
}
}
}
}