Elasticsearch初步使用案例

Elasticsearch的使用數據庫

接下來,咱們看看如何創建索引、建立文檔等,就比如在 MySQL 中進行諸如建立數據庫,插入數據等操做。服務器

Index:建立與更新索引curl

在ElasticSearch中,Index這一動做類比於CRUD中的Create與Update,當咱們嘗試爲某個不存在的文檔創建索引時,會自動根據其相似於ID建立新的文檔,不然就會對原有的文檔進行修改。ui

ElasticSearch使用PUT請求來進行Index操做,你須要提供索引名稱、類型名稱以及可選的ID,格式規範爲:http://localhost:9200//[]。其中索引名稱能夠是任意字符,若是ElasticSearch中並不存在該索引則會自動建立。url

添加文檔
下面,咱們將建立一個存儲電影信息的Document :spa

  • Index 的名稱爲movie
  • Type 的名稱爲adventure
  • Document 有兩個字段: name和actors

咱們使用 Elasticsearch 提供的 RESTful API 來執行上述操做,如圖所示:code

image.png

  • url 表示一個資源,好比 /movie/adventure/1 就表示一個 indexmovietypeadventureid 1document
  • http 方法操做資源,如使用 GET 獲取資源,使用 POST、PUT 新增或更新資源,使用 DELETE 刪除資源等

向指定的 /Index/Type 發送 PUT 請求,就能夠在 Index 裏面新增一條記錄。好比,向/movie/adventure發送請求,就能夠新增電影記錄。對象

咱們可使用 curl 命令來執行上述操做:索引

curl -XPUT "http://localhost:9200/movie/adventure/1" -d '
{
    "name": "Life of Pi",
    "actors": ["Suraj" , "Irrfan"]
}'

若是能夠,推薦使用httpie,相似 curl,但比 curl 更好用,將上面的命令換成 httpie,以下:資源

http put :9200/movie/adventure/1 name="Life of Pi" actors:='["Suraj", "Irrfan"]'

服務器返回的 JSON 對象,會給出 Index、Type、Id、Version 等信息。
成功返回的結果:

{
    "_index": "movie",
    "_type": "adventure",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "created": true
}

能夠看到,咱們已經成功建立了一個 _indexmovie_typeadventure_id 爲 1 的文檔,最後的1是該條記錄的 Id。它不必定是數字,任意字符串(好比abc)均可以。

ElasticSearch對於PUT請求的響應中包含了是否操做成功、文檔編號等信息。

GET
咱們經過 GET 請求來查看這個文檔的信息:

curl -XGET localhost:9200/movie/adventure/1

結果以下:

{
    "_index": "movie",
    "_type": "adventure",
    "_id": "1",
    "_version": 1,
    "found": true,
    "_source": {
        "name": "Life of Pi",
        "actors": [
            "Suraj",
            "Irrfan"
        ]
    }
}

能夠看到,原始的文檔數據存在了 _source 字段中。

新增記錄的時候,也能夠不指定 Id,這時要改爲 「POST」 請求。

curl -X POST 'localhost:9200/movie/adventure' -d '
{
  "name": "Life of Pi"
}'

更新整個文檔
更新記錄就是使用 PUT 請求,從新發送一次數據。不過咱們此次務必要加上須要修改的文檔的ID編號,不然就變成添加了。接下來咱們嘗試對剛纔新創建的文檔進行些修改,添加某些關鍵字屬性。

當咱們使用 PUT 方法指明文檔的 _index, _type _id時,若是 _id 已存在,則新文檔會替換舊文檔,此時文檔的 _version 會增長 1,而且 _created 字段爲 false。好比:

curl -XPUT "http://localhost:9200/movie/adventure/1" -d'
{
    "name": "Life of Pi"
}'

返回的結果:

{
    "_index": "movie",
    "_type": "adventure",
    "_id": "1",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "created": false
}

添加和修改的比較
對於此操做的ElasticSearch的響應與前者很相似,不過能夠看出_version屬性值已經發生了變化:

變化的字段 添加 修改
_version 1 2
result created updated
created true false

GET
最簡單的獲取某個文檔的方式便是基於文檔ID進行搜索

curl -XGET 'http://localhost:9200/movie/adventure/1?pretty=true'

返回的結果:

{
  "_index" : "movie",
  "_type" : "adventure",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "name" : "Life of Pi"
  }
}

能夠看到,actors 這個字段已經不存在了,文檔的 _version 變成了 2。

如何避免原文檔被替換?

所以,爲了不在誤操做的狀況下,原文檔被替換,咱們可使用 _create 這個 API,表示只在文檔不存在的狀況下才建立新文檔(返回 201 Created),若是文檔存在則不作任何操做(返回 409 Conflict),命令以下:

curl -XPUT "http://localhost:9200/movie/adventure/1/_create" -d'
{                       
    "name": "Life of Pi"
}'

因爲文檔 id 存在,會返回 409 Conflict。結果以下:

{
    "error": {
        "root_cause": [
            {
                "type": "version_conflict_engine_exception",
                "reason": "[adventure][1]: version conflict, document already exists (current version [2])",
                "index_uuid": "Kn_OWg1TT5GLaMInWlREHQ",
                "shard": "3",
                "index": "movie"
            }
        ],
        "type": "version_conflict_engine_exception",
        "reason": "[adventure][1]: version conflict, document already exists (current version [2])",
        "index_uuid": "Kn_OWg1TT5GLaMInWlREHQ",
        "shard": "3",
        "index": "movie"
    },
    "status": 409
}

局部更新
在有些狀況下,咱們只想更新文檔的局部,而不是整個文檔,這時咱們可使用 _update 這個 API。

如今,待更新的文檔信息以下:

{
  "_index" : "movie",
  "_type" : "adventure",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "name" : "Life of Pi"
  }
}

最簡單的 update 請求接受一個局部文檔參數 doc,它會合併到現有文檔中,請求方式須要變動爲POST方式:將對象合併在一塊兒,存在的標量字段被覆蓋,新字段被添加。

curl -XPOST "http://localhost:9200/movie/adventure/1/_update" -d'
{
    "doc": {
      "name": "life of pi",
      "actor": ["jack"]
   }
}'

上面的命令中,咱們添加了一個新的字段:actors,結果以下:

{
  "_index" : "movie",
  "_type" : "adventure",
  "_id" : "1",
  "_version" : 8,
  "found" : true,
  "_source" : {
    "name" : "life of pi",
    "actor" : [
      "jack"
    ]
  }
}

Delete:刪除索引
如今咱們嘗試去刪除上文中插入的部分文檔,對於要刪除的文檔一樣須要傳入索引名、類型名與文檔名這些信息,譬如:

curl -XDELETE "http://localhost:9200/movie/adventure/1"

返回的結果:

{
    "found": true,
    "_index": "movie",
    "_type": "adventure",
    "_id": "1",
    "_version": 3,
    "result": "deleted",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    }
}

在咱們刪除了該文檔以後,再次嘗試用GET方法獲取該文檔信息時,會獲得以下的響應:

{
  "_index" : "movie",
  "_type" : "adventure",
  "_id" : "1",
  "found" : false
}

查看當前節點的全部 Index

http://localhost:9200/_cat/indices?v

返回的結果:

health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   my_index    aBM6KLOLSJ6TWtp87sC5qA   5   1          1            0      4.1kb          4.1kb
yellow open   accounts    2i3MNbwCSeSxZCBDikaMzA   5   1          2            0      7.9kb          7.9kb
yellow open   movies      -uB5sD6QTt6vmD4YPpJFaQ   5   1          1            0      5.1kb          5.1kb
yellow open   liuxingwang 6KRPO9fJRVmWC7X3G69HQQ   5   1          0            0       955b           955b

小結

  • Elasticsearch 經過簡單的 RESTful API 來隱藏 Lucene 的複雜性,從而讓全文搜索變得簡單。
  • 在建立文檔時,咱們能夠用 POST 方法指定將文檔添加到某個 _index/_type 下,來讓 Elasticsearch自動生成惟一的 _id
  • 而用 PUT 方法指定將文檔的 _index/_type/_id
  • 咱們看不到HTTP頭是由於咱們沒有讓curl顯示它們,若是要顯示,使用curl命令後跟-i參數。
相關文章
相關標籤/搜索