ElasticSearch簡介和快速實戰

ElasticSearch簡介和快速實戰

ElasticSearch與Lucene

Lucene可以被認爲是迄今爲止最先進、性能最好的、功能最全的搜索引擎庫(框架)

但是想要使用Lucene,必須使用Java來作爲開發語言並將其直接集成到你的應用中,並且Lucene的配置及使用非常複雜,你需要深入瞭解檢索的相關知識來理解它是如何工作的。

Lucene缺點:

1)只能在Java項目中使用,並且要以jar包的方式直接集成項目中.

2)使用非常複雜-創建索引和搜索索引代碼繁雜

3)不支持集羣環境-索引數據不同步(不支持大型項目)

4)索引數據如果太多就不行,索引庫和應用所在同一個服務器,共同佔用硬盤.共用空間少.

上述Lucene框架中的缺點,ES全部都能解決.

ES vs Solr比較

當單純的對已有數據進行搜索時,Solr更快。當實時建立索引時, Solr會產生io阻塞,查詢性能較差, Elasticsearch具有明顯的優勢。二者安裝都很簡單。

1、Solr 利用 Zookeeper 進行分佈式管理,而Elasticsearch 自身帶有分佈式協調管理功能。

2、Solr 支持更多格式的數據,比如JSON、XML、CSV,而 Elasticsearch 僅支持json文件格式。

3、Solr 在傳統的搜索應用中表現好於 Elasticsearch,但在處理實時搜索應用時效率明顯低於 Elasticsearch。

4、Solr 是傳統搜索應用的有力解決方案,但 Elasticsearch更適用於新興的實時搜索應用。

ES vs 關係型數據庫

image

什麼是全文檢索

全文檢索是指:

  • 通過一個程序掃描文本中的每一個單詞,針對單詞建立索引,並保存該單詞在文本中的位置、以及出現的次數
  • 用戶查詢時,通過之前建立好的索引來查詢,將索引中單詞對應的文本位置、出現的次數返回給用戶,因爲有了具體文本的位置,所以就可以將具體內容讀取出來了

分詞原理之倒排索引

image

image

image

倒排索引總結:

索引就類似於目錄,平時我們使用的都是索引,都是通過主鍵定位到某條數據,那麼倒排索引呢,剛好相反,數據對應到主鍵.這裏以一個博客文章的內容爲例:

1.索引

文章ID 文章標題 文章內容
1 淺析JAVA設計模式 JAVA設計模式是每一個JAVA程序員都應該掌握的進階知識
2 JAVA多線程設計模式 JAVA多線程與設計模式結合

2.倒排索引

假如,我們有一個站內搜索的功能,通過某個關鍵詞來搜索相關的文章,那麼這個關鍵詞可能出現在標題中,也可能出現在文章內容中,那我們將會在創建或修改文章的時候,建立一個關鍵詞與文章的對應關係表,這種,我們可以稱之爲倒排索引,因此倒排索引,也可稱之爲反向索引.如:

關鍵詞 文章ID
JAVA 1
設計模式 1,2
多線程 2

注:這裏涉及中文分詞的問題

Elasticsearch中的核心概念

1 索引 index

一個索引就是一個擁有幾分相似特徵的文檔的集合。比如說,可以有一個客戶數據的索引,另一個產品目錄的索引,還有一個訂單數據的索引

一個索引由一個名字來標識(必須全部是小寫字母的),並且當我們要對對應於這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字

2 映射 mapping

ElasticSearch中的映射(Mapping)用來定義一個文檔

mapping是處理數據的方式和規則方面做一些限制,如某個字段的數據類型、默認值、分詞器、是否被索引等等,這些都是映射裏面可以設置的

3 字段Field

相當於是數據表的字段|列

4 字段類型 Type

每一個字段都應該有一個對應的類型,例如:Text、Keyword、Byte等

5 文檔 document

一個文檔是一個可被索引的基礎信息單元,類似一條記錄。文檔以JSON(Javascript Object Notation)格式來表示;

6 集羣 cluster

一個集羣就是由一個或多個節點組織在一起,它們共同持有整個的數據,並一起提供索引和搜索功能

7 節點 node

一個節點是集羣中的一個服務器,作爲集羣的一部分,它存儲數據,參與集羣的索引和搜索功能

一個節點可以通過配置集羣名稱的方式來加入一個指定的集羣。默認情況下,每個節點都會被安排加入到一個叫做“elasticsearch”的集羣中

這意味着,如果在網絡中啓動了若干個節點,並假定它們能夠相互發現彼此,它們將會自動地形成並加入到一個叫做“elasticsearch”的集羣中

在一個集羣裏,可以擁有任意多個節點。而且,如果當前網絡中沒有運行任何Elasticsearch節點,這時啓動一個節點,會默認創建並加入一個叫做“elasticsearch”的集羣。

3.8 分片和副本 shards&replicas

3.8.1 分片

  • 一個索引可以存儲超出單個結點硬件限制的大量數據。比如,一個具有10億文檔的索引佔據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢

  • 爲了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片

  • 當創建一個索引的時候,可以指定你想要的分片的數量

  • 每個分片本身也是一個功能完善並且獨立的“索引”,這個“索引”可以被放置到集羣中的任何節點上

  • 分片很重要,主要有兩方面的原因

​ 允許水平分割/擴展你的內容容量

​ 允許在分片之上進行分佈式的、並行的操作,進而提高性能/吞吐量

  • 至於一個分片怎樣分佈,它的文檔怎樣聚合回搜索請求,是完全由Elasticsearch管理的,對於作爲用戶來說,這些都是透明的

3.8.2 副本

  • 在一個網絡/雲的環境裏,失敗隨時都可能發生,在某個分片/節點不知怎麼的就處於離線狀態,或者由於任何原因消失了,這種情況下,有一個故障轉移機制是非常有用並且是強烈推薦的。爲此目的,Elasticsearch允許你創建分片的一份或多份拷貝,這些拷貝叫做副本分片,或者直接叫副本

  • 副本之所以重要,有兩個主要原因

​ 1) 在分片/節點失敗的情況下,提供了高可用性。

​ 注意到複製分片從不與原/主要(original/primary)分片置於同一節點上是非常重要的

​ 2) 擴展搜索量/吞吐量,因爲搜索可以在所有的副本上並行運行

​ 每個索引可以被分成多個分片。一個索引有0個或者多個副本

​ 一旦設置了副本,每個索引就有了主分片和副本分片,分片和副本的數量可以在索引

​ 創建的時候指定

​ 在索引創建之後,可以在任何時候動態地改變副本的數量,但是不能改變分片的數量

測試分詞效果

單字分詞器

POST _analyze
 {
 "analyzer":"standard",
 "text":"我愛你中國"
 }

ik分詞器

最粗力度拆分

POST _analyze
{
"analyzer": "ik_smart",
"text": "中華人民共和國人民大會堂"
}

最細力度拆分

POST _analyze
{
"analyzer": "ik_max_word",
"text": "中華人民共和國人民大會堂"
}

指定IK分詞器作爲默認分詞器

修改默認分詞方法(這裏修改school_index索引的默認分詞爲:ik_max_word):

PUT /school_index
{
  "settings" :  {
    "index" : {
    "analysis.analyzer.default.type": "ik_max_word"
    }
  }
}

ES數據管理

ES是面向文檔(document oriented)的,這意味着它可以存儲整個對象或文檔(document)。

然而它不僅僅是存儲,還會索引(index)每個文檔的內容使之可以被搜索。

在ES中,你可以對文檔(而非成行成列的數據)進行索引、搜索、排序、過濾。

ES使用JSON作爲文檔序列化格式。

JSON現在已經被大多語言所支持,而且已經成爲NoSQL領域的標準格式。

ES存儲的一個員工文檔的格式示例:

{
"email": "[email protected]",
"name": "張三",
 "age": 30,
 "interests": [ "籃球", "健身" ]

}

基本操作

1) 創建索引

格式: PUT /索引名稱

PUT /es_db 

2) 查詢索引

格式: GET /索引名稱

GET /es_db

3) 刪除索引

格式: DELETE /索引名稱

DELETE /es_db

4) 添加文檔

格式: PUT /索引名稱/類型/id

PUT /es_db/_doc/1{"name": "張三","sex": 1,"age": 25,"address": "廣州天河公園","remark": "java developer"}PUT /es_db/_doc/2{"name": "李四","sex": 1,"age": 28,"address": "廣州荔灣大廈","remark": "java assistant"}PUT /es_db/_doc/3{"name": "rod","sex": 0,"age": 26,"address": "廣州白雲山公園","remark": "php developer"}PUT /es_db/_doc/4{"name": "admin","sex": 0,"age": 22,"address": "長沙橘子洲頭","remark": "python assistant"}PUT /es_db/_doc/5{"name": "小明","sex": 0,"age": 19,"address": "長沙嶽麓山","remark": "java architect assistant"}		

5) 修改文檔

格式: PUT /索引名稱/類型/id

PUT /es_db/_doc/1{"name": "白起老師","sex": 1,"age": 25,"address": "張家界森林公園","remark": "php developer assistant"				}

注意:

POST和PUT都能起到創建/更新的作用

1、需要注意的是PUT需要對一個具體的資源進行操作也就是要確定id才能進行更新/創建,而POST是可以針對整個資源集合進行操作的,如果不寫id就由ES生成一個唯一id進行創建新文檔,如果填了id那就針對這個id的文檔進行創建/更新

2、PUT只會將json數據都進行替換, POST只會更新相同字段的值

3、PUT與DELETE都是冪等性操作, 即不論操作多少次, 結果都一樣

6) 查詢文檔

格式: GET /索引名稱/類型/id

GET /es_db/_doc/1

7) 刪除文檔

格式: DELETE /索引名稱/類型/id

DELETE /es_db/_doc/1

Restful風格

Restful是一種面向資源的架構風格,可以簡單理解爲:使用URL定位資源,用HTTP動詞(GET,POST,DELETE,PUT)描述操作。 基於Restful API ES和所有客戶端的交互都是使用JSON格式的數據.

其他所有程序語言都可以使用RESTful API,通過9200端口的與ES進行通信

GET查詢

PUT添加

POST修改

DELE刪除

使用Restful的好處:

透明性,暴露資源存在。

充分利用 HTTP 協議本身語義,不同請求方式進行不同的操作

查詢操作

1 查詢當前類型中的所有文檔

格式: GET /索引名稱/類型/_search

GET /es_db/_doc/_search

SQL: select * from student

2 條件查詢

如要查詢age等於28歲的

格式: GET /索引名稱/類型/_search?q=age:28

GET /es_db/_doc/_search?q=age:28

SQL: select * from student where age = 28

3 範圍查詢

如要查詢age在25至26歲之間的

格式: GET /索引名稱/類型/_search?q=age[25 TO 26] 注意: TO 必須爲大寫

GET /es_db/_doc/_search?q=age[25 TO 26]

SQL: select * from student where age between 25 and 26

4 根據多個ID進行批量查詢 _mget

格式: GET /索引名稱/類型/_mget

GET /es_db/_doc/_mget{  "ids":["2","3"] }

select * from student where id in (2,3)

5 查詢年齡小於等於28歲的 :<=

格式: GET /索引名稱/類型/_search?q=age:<=28

GET /es_db/_doc/_search?q=age:<=28

SQL: select * from student where age <= 28

6 查詢年齡大於28前的 :>

格式: GET /索引名稱/類型/_search?q=age:>26

GET /es_db/_doc/_search?q=age:>26

SQL: select * from student where age > 28

7 分頁查詢

格式: GET /索引名稱/類型/_search?q=age[25 TO 26]&from=0&size=1

GET /es_db/_doc/_search?q=age[25 TO 26]&from=0&size=1

SQL: select * from student where age between 25 and 26 limit 0, 1

8 對查詢結果只輸出某些字段**

格式: GET /索引名稱/類型/_search?__source=字段,字段

GET /es_db/_doc/_search?_source=name,age

SQL: select name,age from student

9 對查詢結果排序**

格式: GET /索引名稱/類型/_search?sort=字段 desc

GET /es_db/_doc/_search?sort=age:desc

SQL: select * from student order by age desc

文檔批量操作

1.批量獲取文檔數據

批量獲取文檔數據是通過_mget的API來實現的

(1)在URL中不指定index和type

  • 請求方式:GET

  • 請求地址:_mget

  • 功能說明 : 可以通過ID批量獲取不同index和type的數據

  • 請求參數:

    • docs : 文檔數組參數
      • _index : 指定index
      • _type : 指定type
      • _id : 指定id
      • _source : 指定要查詢的字段
GET _mget{  "docs": [    {      "_index": "es_db",      "_id": 3    },    {      "_index": "es_db",      "_id": 2    }  ]}

(2)在URL中指定index

  • 請求方式:GET

  • 請求地址:/{{indexName}}/_mget

  • 功能說明 : 可以通過ID批量獲取不同index和type的數據

  • 請求參數:

    • docs : 文檔數組參數
      • _index : 指定index
      • _type : 指定type
      • _id : 指定id
      • _source : 指定要查詢的字段
GET /es_db/_mget{  "docs": [    {      "_type":"_doc",      "_id": 3    },    {      "_type":"_doc",      "_id": 4    }  ]}

(3)在URL中指定index和type

  • 請求方式:GET

  • 請求地址:/{{indexName}}/{{typeName}}/_mget

  • 功能說明 : 可以通過ID批量獲取不同index和type的數據

  • 請求參數:

    • docs : 文檔數組參數
      • _index : 指定index
      • _type : 指定type
      • _id : 指定id
      • _source : 指定要查詢的字段
GET /es_db/_doc/_mget{  "docs": [    {      "_id": 3    },    {      "_id": 2    }  ]}
2.批量操作文檔數據

批量對文檔進行寫操作是通過_bulk的API來實現的

  • 請求方式:POST

  • 請求地址:_bulk

  • 請求參數:通過_bulk操作文檔,一般至少有兩行參數(或偶數行參數)

    • 第一行參數爲指定操作的類型及操作的對象(index,type和id)
    • 第二行參數纔是操作的數據

參數類似於:

{"actionName":{"_index":"indexName", "_type":"typeName","_id":"id"}}{"field1":"value1", "field2":"value2"}
  • actionName:表示操作類型,主要有create,index,delete和update

(1)批量創建文檔create

POST _bulk{"create":{"_index":"article",  "_id":3}}{"id":3,"title":"白起老師1","content":"白起老師666","tags":["java", "面向對象"],"create_time":1554015482530}{"create":{"_index":"article", "_id":4}}{"id":4,"title":"白起老師2","content":"白起老師NB","tags":["java", "面向對象"],"create_time":1554015482530}

(2)普通創建或全量替換index

POST _bulk{"index":{"_index":"article",  "_id":3}}{"id":3,"title":"圖靈徐庶老師(一)","content":"圖靈學院徐庶老師666","tags":["java", "面向對象"],"create_time":1554015482530}{"index":{"_index":"article",  "_id":4}}{"id":4,"title":"圖靈諸葛老師(二)","content":"圖靈學院諸葛老師NB","tags":["java", "面向對象"],"create_time":1554015482530}

(3)批量刪除delete

POST _bulk{"delete":{"_index":"article", "_id":3}}{"delete":{"_index":"article", "_id":4}}

(4)批量修改update

POST _bulk{"update":{"_index":"article",  "_id":3}}{"doc":{"title":"ES大法必修內功"}}{"update":{"_index":"article",  "_id":4}}{"doc":{"create_time":1554018421008}}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章