ElasticSearch核心概念和文檔的CRUD



本文所有命令均在 Kibana 的 dev tools 上進行

1. 基本概念

1.1 Node 與 Cluster

Elastic 本質上是一個分布式數據庫,允許多台服務器協同工作,每台服務器可以運行多個 Elastic 實例。單個 Elastic 實例稱為一個節點(node)。一組節點構成一個集群(cluster)。

1.2 Index

Elastic 會索引所有字段,經過處理后寫入一個反向索引(Inverted Index)。查找數據的時候,直接查找該索引。所以,Elastic 數據管理的頂層單位就叫做 Index(索引)。它是單個數據庫的同義詞。每個 Index (即數據庫)的名字必須是小寫。

事實上,我們的數據被存儲在分片(shards)中,索引只是一個把一個或多個分片分組在一起的邏輯空間。然而,這只是一些內部細節——我們的程序完全不用關心分片。對於我們的程序而言,文檔存儲在索引(index)中。剩下的細節由Elasticsearch關心既可。

可以使用如下命令,查詢本節點下的所有索引

#查詢所有索引
GET _cat/indices?v

可以得到以下結果

health status index     uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   idx5      Tzjr1CmGRlCOjZUyQ0QUhA   3   0          2            0      8.5kb          8.5kb
yellow open   idx4      z7zw83L9Tjyc1Fx7jb6l0A   1   1          3            1     11.8kb         11.8kb
green  open   idx2      7SSk77DkTN-VpUuXehgaDQ   3   0          7            2     27.2kb         27.2kb
yellow open   idx1      1bqxLckjSk-BZtERVNhPZQ   1   1          0            0       283b           283b
green  open   idx3      qc32ybYBT869QIPaYmcWGQ   3   0          0            0       849b           849b

你可能還注意到客戶索引標記了黃色運行狀況。黃色表示某些副本尚未分配。 此索引發生這種情況的原因是因為默認情況下Elasticsearch為此索引創建了一個副本。 由於我們目前只有一個節點在運行,因此在另一個節點加入集群的稍后時間點之前,尚無法分配一個副本(用於高可用性)。 將該副本分配到第二個節點后,此索引的運行狀況將變為綠色。

創建索引(使用默認的設置)

PUT idx1/

創建索引同時指定節點的復制和分片數量

PUT idx2/
{
  "settings": {
    "index": {
        "number_of_shards" : "3",
        "number_of_replicas" : "0"
    }
  }
}

查詢索引的基本信息

GET idx2/

獲取所有索引的設置

GET _all/_settings

刪除索引

DELETE idx3/

1.3 Document

Index 里面單條的記錄稱為 Document(文檔)。許多條 Document 構成了一個 Index。

Document 使用 JSON 格式表示,下面是一個例子。

{
  "_index" : "idx2",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 5,
  "_seq_no" : 5,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "BiologyBook2.0",
    "price" : 100.0
  }
}

同一個 Index 里面的 Document,不要求有相同的結構(scheme),但是最好保持相同,這樣有利於提高搜索效率。但是在 es6.0 后續版本中廢除了 type,推薦所有的 Document 均默認使用 _doc 類型。

1.4 Type(將在ES6.0移除)

Document 可以分組,比如weather這個 Index 里面,可以按城市分組(北京和上海),也可以按氣候分組(晴天和雨天)。這種分組就叫做 Type,它是虛擬的邏輯分組,用來過濾 Document。

2. 數據的增刪改查

2.1 添加數據

在 es7.x 之后取消了 type,均使用_doc同一文檔類型,想必之后版本連_doc也會被取消。

向指定的 /Index/Type 發送 PUT 請求,就可以在 Index 里面新增一條記錄。比如,向/idx1/_doc發送請求,就可以新增一條人員記錄。

POST /idx4/_doc/
{
  "name" : "anqi1.0",
  "age" : 20
}

我們會得到如下 json 結果,其中_id為該記錄id,如果沒指定的話 es 會幫我生成這種隨機id,result為我們執行的操作,_index為所屬索引

{
  "_index" : "idx4",
  "_type" : "_doc",
  "_id" : "0u8pvGsB-aEEelT0MVgW",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

我們也可以指定生成的id,這樣的話得到的_id就為我們指定的數字1

POST /idx4/_doc/1
{
  "name" : "anqi1.0",
  "age" : 20
}

我們如果對不存在的文檔執行更新操作,則會新增一條數據,

PUT /idx4/_doc/2
{
  "age" : 33
}

得到如下結果,當然我們不提倡統一索引下存放結構不一樣的數據。(因為只有一個 age 屬性)

{
  "_index" : "idx4",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

2.2 查詢數據

根據id獲取文檔

GET /idx5/_doc/1

使用如下命令查詢 idx5 索引下所有數據

GET /idx5/_search

得到如下結果, _source即為插入的數據

{
  "took" : 353,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {"value" : 2,"relation" : "eq"},
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "idx5",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "city" : "Yuanping",
          "email" : "123@qq.com"
        }
      },
      {
        "_index" : "idx5",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "city" : "Xinzhou",
          "email" : "abc@qq.com"
        }
      }
    ]
  }
}

上面代碼中,返回結果的 took字段表示該操作的耗時(單位為毫秒),timed_out字段表示是否超時,hits字段表示命中的記錄,里面子字段的含義如下。

  • total:返回記錄數,本例是2條。
  • max_score:最高的匹配程度,本例是1.0
  • hits:返回的記錄組成的數組。

返回的記錄中,每條記錄都有一個_score字段,表示匹配的程序,默認是按照這個字段降序排列。

2.3 更新數據

更新數據就是發送 PUT請求,我們這里將id為1的數據中age屬性更新為 22

PUT /idx4/_doc/1
{
  "age" : 22
}

更新后我們得到了以下結果

{
  "_index" : "idx4",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

可以看到,記錄的 Id 沒變,但是版本(version)從1變成2,操作類型(result)從created變成updated,因為這次不是新建記錄

Elasticsearch是一個分布式系統。當documents被創建、更新或者刪除,其新版本會被復制到集群的其它節點。Elasticsearch既是異步的(asynchronous )也是同步的(concurrent),其含義是復制請求都是並行發送的,但是到達目的地的順序是無序的。Elasticsearch系統需要一種方法使得老版本的文檔永遠都無法覆蓋新的版本。

每當文檔被改變的時候,文檔中的_version將會被增加(+1)。Elasticsearch使用_version確保所有的修改都會按照正確的順序執行。如果文檔舊的版本在新的版本之后到達,它會被簡單的忽略。

2.4 刪除數據

刪除數據就是發送 DELETE 請求

DELETE /idx4/_doc/1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM