Elasticsearch:索引,映射,文檔操作

摘要: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": "蘇州"
      }
    }
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容