首頁 > 軟體

搜尋一文入門ElasticSearch(節點 分片 CRUD 倒排索引 分詞)

2023-03-23 22:03:57

ElasticSearch

ElasticSearch是非常重要的檢索工具,利用分詞、索引(倒排索引)、分詞從眾多檢索工具中脫穎而出,本章是入門基礎學習篇內容。

基本概念:索引、檔案和REST Api

ElasticSearch是面向檔案的,檔案是所有可搜尋資料的最小單位

  • 紀錄檔檔案中的紀錄檔項
  • 一本電影的具體資訊 / 一張唱片的詳細資訊
  • Mp3播放器的一首歌 / 一篇PDF檔案中的具體內容

檔案會被序列化成Josn格式,儲存在ElasticSearch中

  • Json物件由欄位組成
  • 每個欄位都有對應的欄位型別(字串/數值/布林/日期/二進位制/範圍型別)

每個檔案都有一個UniqueID

你可以自己指定ID

或者通過ElasticSearch自動生成

Json檔案

  • 一篇檔案包含了一系列的欄位
  • Json檔案,格式靈活,不需要預先定義格式
    • 欄位的型別可以指定或通過ElasticSearch自動推算
    • 支援陣列、支援巢狀

檔案的後設資料

{
    "_index" : ".kibana_1",
    "_type" : "_doc",
    "_id" : "space:default",
    "_score" : 1.0,
    "_source" : {
        "space" : {
        "name" : "預設值",
        "description" : "這是您的預設空間!",
        "color" : "#00bfb3",
        "_reserved" : true
        },
        "type" : "space",
        "references" : [ ],
        "updated_at" : "2022-05-13T09:16:16.465Z"
    }
}
  • 後設資料,用於標註檔案的相關資訊
    • _index : 檔案所屬的索引名
    • _type : 檔案所屬的型別名
    • _id : 檔案唯一ID
    • _source : 檔案的原始Json資料
    • _version : 檔案的版本資訊
    • _score : 相關性打分

索引

  • index :索引是檔案的容器,是一類檔案的結合
    • index體現了邏輯空間的概念,每個索引都有自己的Mapping定義,用於定義包含的檔案的欄位名和欄位型別
    • Shard 體現了物理空間的概念,索引中的資料分散在Shard上
  • 索引的Mapping與Settings
    • Mapping定義檔案的欄位型別
    • Setting定義不同的資料分佈
//檢視索引相關資訊
GET kibana_sample_data_ecommerce
//檢視索引的檔案總數
GET kibana_sample_data_ecommerce/_count
//檢視前10條檔案,瞭解檔案格式
POST kibana_sample_data_ecommerce/_search
{
}
//_cat indices API
//檢視indices
GET /_cat/indices/kibana*?v&s=index
//檢視狀態為綠的索引
GET /_cat/indices?v&health=green
//按照檔案個數排序
GET /_cat/indices?v&s=docs.count:desc
//檢視具體的欄位
GET /_cat/indices/kibana*?pri&v&h=health,index,pri,rep,docs.count,mt
//How much memory is used per index?
GET /_cat/indices?v&h=i,tm&s=tm:desc

分散式系統的可用性和擴充套件性

  • 高可用性
    • 服務可用性 :允許有節點停止服務
    • 資料可用性 :部分節點丟失,不會丟失資料
  • 可延伸性
    • 請求量提升 / 資料的不斷增長(將資料分佈都所有接點上)

分散式特性

  • elasticsearch的分散式架構的好處
    • 儲存的水平擴容
    • 提高系統的可用性,部分節點停止服務,整個叢集的服務不受影響
  • elasticsearch的分散式架構
    • 不同的叢集通過不同的名字來區分,預設名字"elasticsearch"
    • 通過組態檔修改,或者在命令列中-E cluster.name=stark進行設定
    • 一個叢集可以有一個或多個節點

節點

  • 節點是elasticsearch的範例
    • 本質上就是一個Java程序
    • 一臺機器上可以執行多個elasticsearch程序,但是生產環境一般建議一臺機器上只執行一個elasticsearch範例
  • 每一個節點都有名字,通過組態檔設定,或者啟動的時候-E node.name=node1指定
  • 每一個節點在啟動之後,會分配一個UID,儲存在data目錄下

分片

  • 主分片,用以解決資料水平擴充套件的問題。通過主分片,可以將資料分佈到叢集內的所有節點之上
    • 一個分片是一個執行的Lucene的範例
    • 主分片數在索引建立時指定,後續不允許修改,除非Reindex
  • 副本 ,用以解決資料高可用的問題,分片是主分片的拷貝
    • 副本分片數,可以動態調整
    • 增加副本數,還可以在一定程度上提高服務的可用性
{
    "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 1
    }
}

檢視叢集的健康狀況

  • Green - 主分片與副本都正常分配
  • Yellow - 主分片全部正常分配,有副本分片未能正常分片
  • Red - 有主分片未能分配

CRUD

1.使用PostMan建立一個名字叫stark的索引

http://127.0.0.1:9200/stark?pretty
// 返回值
{
    "acknowledged": true,
    "shards_acknowledged": true,
    "index": "stark"
}

檔案的CRUD

  • Type名,約定都用_doc
  • Create ,如果ID已經存在,會失敗
  • Index ,如果ID不存在,建立新的檔案。否則先刪除現有檔案,再建立新的檔案,版本會增加。
  • Update ,檔案必須已經存在,更新只會對相應欄位做增量修改。

Create 一個檔案

支援自動生成檔案ID和指定檔案ID兩種方式:

  • 使用POST /indexName/_doc,系統會自動生成Document ID
  • 使用PUT /indexName/_create/ID建立時,URI中顯示指定_create,此時如果該ID的檔案已經存在,操作失敗

GET 一個檔案

GET http://127.0.0.1:9200/IndexName/_doc/ID

  • 找到檔案,返回Http 200
    • 檔案元資訊,同一個ID的檔案,即使被刪除,Version號也會不斷增加
    • _source 中預設包含了檔案的所有原始資訊
  • 找不到檔案,返回Http 404

Index 檔案

PUT IndexName/_doc/1
{
    "tags":["name","age","sex"]
}

Index和Create不一樣的地方:如果檔案存在,就索引新的檔案。否則現有檔案會被刪除,新的檔案被索引,版本資訊(Version) + 1。

Update 檔案

Update方法不會刪除原來的檔案,而是實現真正的資料更新,POST方法 ,Payload需要包含在doc中。

POST IndexNmae/_update/1
{
    "doc":{
        "albums":["aaa","bbb"]
    }
}

刪除檔案

DELETE IndexName/_doc/ID

Bulk API / 批次讀取 mGet / 批次查詢 msearch

Bulk Api 支援在一次Api呼叫中,對不同的索引進行操作,支援四種型別操作,IndexCreateUpdateDelete。

可以在URI中指定Index,也可以在請求的Payload中進行,操作單挑操作失敗,並不影響其他操作,返回結果包括了每一條操作執行的結果。

//對同一個索引進行操作
POST /IndexName/_doc/_bulk 
//對不同的索引進行操作
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test2", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

mGet批次操作,可以減少網路連結所產生的開銷,提高效能。

#URI中指定index
GET /IndxName/_mget
{
    "docs" : [
        {
            "_id" : "1"
        },
        {
            "_id" : "2"
        }
    ]
}
//對不同的索引進行操作
GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_id" : "1"
        },
        {
            "_index" : "test",
            "_id" : "2"
        }
    ]
}

批次查詢 msearch

// msearch 操作
POST kibana_sample_data_ecommerce/_msearch
{"query" : {"match_all" : {}},"size":1}
{"index" : "kibana_sample_data_flights"}
{"query" : {"match_all" : {}},"size":2}

倒排索引

倒排索引的核心組成

  • 倒排索引包含兩個部分
    • 單詞詞典,記錄所有檔案的單詞,記錄單詞到倒排列表的關聯關係
      • 單詞詞典一般比較大,可以通過B+樹或雜湊拉鍊法實現,以滿足高效能的插入和查詢
    • 倒排列表,記錄了單詞對應的檔案結合,由倒排索引組成
      • 倒排索引項
        • 檔案ID
        • 詞頻TF - 該單詞在檔案中出現的次數,用於相關性評分
        • 位置,單詞在檔案中分詞的位置,用於語句搜尋
        • 偏移,記錄單詞的開始結束位置,實現高亮顯示

Es的倒排索引

  • Es的Json檔案中的每個欄位,都有自己的倒排索引
  • 可以指定對某些欄位不做索引
    • 優點:節省儲存空間
    • 缺點:欄位無法被搜尋

Analysis 與 Analyzer

  • Analysis,文字分析是把全文字轉換成一系列單詞(term / token)的過程,也叫分詞。
  • Analysis 是通過 Analyzer 來實現的,可使用elasticsearch內建的分析器 / 或者按需客製化化分析器。
  • 除了在資料寫入時轉換詞條,匹配Query語句時候也需要用相同的分析器對查詢進行查詢語句進行分析。

Analyzer的組成

  • 分詞器是專門處理分詞的元件,Analyzer由三部分組成:
    • ① 針對原始文書處理,例如去除html
    • ② 按照規則切分單詞
    • ③ 將切分的單詞進行加工,小寫,刪除stopworlds,增加同義詞

Search Api

  • URI Search ,在URL中使用查詢引數
  • Request Body Search ,使用es提供的,基於Json格式的更加完備的Query Domain Specific Language(DSL)

1.指定查詢的索引

叢集上所有的索引:

GET /_search //叢集上所有的索引
GET /Index1/_search  //index1
GET /Index1,Index2/_search  //index1和index2
GET /index*/_search  //以index開頭的索引

2.URI查詢

  • 使用"q",指定字串查詢
  • "query string syntax",KV鍵值對

用q表示查詢內容,搜尋叫做stark的客戶GET /IndexName/_search?q=keyName:stark

3.Request Body

Request Body 支援 POST/GET兩種方法,-H代表的是header引數 -d 代表的是body的請求引數。

curl -XGET "http://127.0.0.1:9200/IndexName/_search"
-H 'Content-Type:application/json' 
-d
'
{
 "query":{
     "match_all":{}
 }    
}
'

4.搜尋Response

搜尋Response有幾個關鍵的描述需要在這裡解釋一下:

  • took: 花費的時間
  • total: 符合條件的總檔案數
  • hits:結果集,預設前10個檔案
  • _index:索引名
  • _id:檔案的ID
  • _score: 相關度評分
  • _source:檔案原始資訊

URI Search詳解

指定欄位查詢 Vs 泛查詢

q是關鍵字,df是指定欄位,泛查詢就是查詢所有欄位中包含關鍵字的結果

//指定欄位
GET /IndexName/_search?q=2020&df=title
GET /IndexName/_search?q=title:2020
{
    "profile":"true"
}
//泛查詢
GET /IndexName/_search?q=2020
{
    "profile":"true"
}

Term Vs Phrase

Hello World 等效於 Hello Or World

"Hello World",等效於Hello AND World 。Phrase查詢,還要求前後順序保持一致

分組和引號

  • title:(Hello AND World)
  • title = "Hello World"
//分組,Bool查詢
GET /IndexName/_search?q=title:(Hello World)
{
    "profile":"true"
}
//泛查詢
GET /IndexName/_search?q=title:Hello World
{
    "profile":"true"
}

布林操作 、分組

  • 布林操作
    • AND / OR / NOT 或者 && / || / !
      • 必須大寫
      • title:(Hello NOT World)
  • 分組
      • 表示 must
      • 表示 must_not
    • title:(+Hello -World)
//檢索title裡有Hello ,沒有World的詞條
GET /IndexName/_search?q=title:(Hello NOT World)
{
    "profile":"true"
}
//檢索title裡必須有Hello ,必須沒有World的詞條
GET /IndexName/_search?q=title:(+Hello -World)
{
    "profile":"true"
}

範圍查詢 、算術符號

URI Search支援範圍查詢和算術符號查詢。

  • 範圍查詢
    • 區間表示:[]閉區間,{}開區間
    • year:{2019 TO 2020}
    • year:[* TO 2020]
  • 算數符號
    • year:> 2020
    • year:(>2010 && < 2020)
    • year:(+>2010 && +< 2020)
GET /IndexName/_search?q=year:>2020
{
    "profile":"true"
}

萬用字元查詢 、正規表示式 、模糊匹配與近似查詢

萬用字元查詢 、正規表示式 、模糊匹配與近似查詢效率低,佔用記憶體大,不建議使用,這部分大家有個瞭解就好。

以上就是搜尋一文入門ElasticSearch(節點 分片 CRUD 倒排索引 分詞)的詳細內容,更多關於ElasticSearch搜尋入門的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com