1.ElasticSearch簡介
1.1 ElasticSearch(簡稱ES)
Elasticsearch是用Java開發并且是當前最流行的開源的企業級搜索引擎。能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
1.2 ElasticSearch與Lucene的關系
Lucene可以被認為是迄今為止最先進、性能最好的、功能最全的搜索引擎庫(框架)
但是想要使用Lucene,必須使用Java來作為開發語言并將其直接集成到你的應用中,并且Lucene的配置及使用非常復雜,你需要深入了解檢索的相關知識來理解它是如何工作的。
Lucene缺點:
1)只能在Java項目中使用,并且要以jar包的方式直接集成項目中.
2)使用非常復雜-創建索引和搜索索引代碼繁雜
3)不支持集群環境-索引數據不同步(不支持大型項目)
4)索引數據如果太多就不行,索引庫和應用所在同一個服務器,共同占用硬盤.共用空間少.
2. Lucene全文檢索框架
2.1 什么是全文檢索
數據總體分為兩種:結構化數據和非結構化數據。
結構化數據:指具有固定格式或有限長度的數據,如數據庫,元數據等。
非結構化數據:指不定長或無固定格式的數據,如 互聯網數據、郵件,word文檔等。
即全文數據的搜索主要有兩種方法:順序掃描法和反向索引法
順序掃描法:所謂順序掃描法,就是順序掃描每個文檔內容,看看是否有要搜索的關鍵字,實現查 找文檔的功能,也就是根據文檔找詞。
反向索引法:所謂反向索引,就是提前將搜索的關鍵字建成索引,然后再根據索引查找文檔,也就 是根據詞找文檔。
這種先建立 索引 ,再對索引進行 搜索 文檔的過程就叫 全文檢索(Full**-**text Search) 。
全文檢索是指:
- 通過一個程序掃描文本中的每一個單詞,針對單詞建立索引,并保存該單詞在文本中的位置、以及出現的次數
- 用戶查詢時,通過之前建立好的索引來查詢,將索引中單詞對應的文本位置、出現的次數返回給用戶,因為有了具體文本的位置,所以就可以將具體內容讀取出來了
2.2 分詞原理之倒排索引
倒排索引總結:
索引就類似于目錄,平時我們使用的都是索引,都是通過主鍵定位到某條數據,那么倒排索引呢,剛好相反,數據對應到主鍵.這里以一個博客文章的內容為例:
1.索引
文章ID | 文章標題 | 文章內容 |
---|---|---|
1 | 淺析JAVA設計模式 | JAVA設計模式是每一個JAVA程序員都應該掌握的進階知識 |
2 | JAVA多線程設計模式 | JAVA多線程與設計模式結合 |
2.倒排索引
假如,我們有一個站內搜索的功能,通過某個關鍵詞來搜索相關的文章,那么這個關鍵詞可能出現在標題中,也可能出現在文章內容中,那我們將會在創建或修改文章的時候,建立一個關鍵詞與文章的對應關系表,這種,我們可以稱之為倒排索引,因此倒排索引,也可稱之為反向索引.如:
關鍵詞 | 文章ID |
---|---|
JAVA | 1 |
設計模式 | 1,2 |
多線程 | 2 |
注:這里涉及中文分詞的問題
3. Elasticsearch中的核心概念
3.1 索引 index
? 一個索引就是一個擁有幾分相似特征的文檔的集合。比如說,你可以有一個客戶數據的索引,另一個產 品目錄的索引,還有一個訂單數據的索引。一個索引由一個名字來標識(必須全部是小寫字母的),并 且當我們要對對應于這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字。在 一個集群中,可以定義任意多的索引。
3.2 映射 mapping
ElasticSearch中的映射(Mapping)用來定義一個文檔
mapping是處理數據的方式和規則方面做一些限制,如某個字段的數據類型、默認值、分詞器、是否被索引等等,這些都是映射里面可以設置的
3.3 字段Field
? 相當于是數據表的字段|列,對文檔數據根據不同屬性進行的分類標識
3.4 字段類型 Type
? 每一個字段都應該有一個對應的類型,例如:Text、Keyword、Byte等.
? 在一個索引中,你可以定義一種或多種類型。一個類型是你的索引的一個邏輯上的分類/分區,其語義 完全由你來定。通常,會為具有一組共同字段的文檔定義一個類型。比如說,我們假設你運營一個博客 平臺并且將你所有的數據存儲到一個索引中。在這個索引中,你可以為用戶數據定義一個類型,為博客
? 數據定義另一個類型,當然,也可以為評論數據定義另一個類型。
3.5 文檔 document
? 一個文檔是一個可被索引的基礎信息單元,類似一條記錄。文檔以JSON(Javascript Object Notation)格式來表示;。比如,你可以擁有某一個客戶的文檔,某一個產品的一個文 檔,當然,也可以擁有某個訂單的一個文檔。文檔以JSON(Javascript Object Notation)格式來表 示,而JSON是一個到處存在的互聯網數據交互格式。 在一個index/type里面,你可以存儲任意多的文檔。注意,盡管一個文檔,物理上存在于一個索引之 中,文檔必須被索引/賦予一個索引的type。
3.6 集群 cluster
? 一個集群就是由一個或多個節點組織在一起,它們共同持有整個的數據,并一起提供索引和搜索功能
3.7 節點 node
? 一個節點是集群中的一個服務器,作為集群的一部分,它存儲數據,參與集群的索引和搜索功能
3.8 分片和副本 shards&replicas
3.8.1 分片
? 一個索引可以存儲超出單個結點硬件限制的大量數據。比如,一個具有10億文檔的索引占據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢
? 為了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片。
? 每個分片本身也是一個功能完善并且獨立的“索引”,這個“索引”可以被放置到集群中的任何節點上
分片很重要,主要有兩方面的原因
允許水平分割/擴展你的內容容量允許在分片之上進行分布式的、并行的操作,進而提高性能/吞吐量
至于一個分片怎樣分布,它的文檔怎樣聚合回搜索請求,是完全由Elasticsearch管理的,對于作為用戶來說,這些都是透明的
3.8.2 副本
? 在一個網絡/云的環境里,失敗隨時都可能發生,在某個分片/節點不知怎么的就處于離線狀態,或者由于任何原因消失了,這種情況下,有一個故障轉移機制是非常有用并且是強烈推薦的。為此目的,Elasticsearch允許你創建分片的一份或多份拷貝,這些拷貝叫做副本分片,或者直接叫副本
- 副本之所以重要,有兩個主要原因
- 在分片/節點失敗的情況下,提供了高可用性。
注意到復制分片從不與原/主要(original/primary)分片置于同一節點上是非常重要的
- 擴展搜索量/吞吐量,因為搜索可以在所有的副本上并行運行
每個索引可以被分成多個分片。一個索引有0個或者多個副本
一旦設置了副本,每個索引就有了主分片和副本分片,分片和副本的數量可以在索引
創建的時候指定
在索引創建之后,可以在任何時候動態地改變副本的數量,但是不能改變分片的數量
8.ES數據管理
38.1 基本操作
- 創建索引
格式: PUT /索引名稱 舉例: PUT /es_db
- 查詢索引
格式: GET /索引名稱 舉例: GET /es_db
- 刪除索引
格式: DELETE /索引名稱 舉例: DELETE /es_db
- 添加文檔
格式: PUT /索引名稱/類型/id
- 修改文檔
格式: PUT /索引名稱/類型/id
注意:POST和PUT都能起到創建/更新的作用
1、需要注意的是PUT需要對一個具體的資源進行操作也就是要確定id才能進行更新/創建,而POST是可以針對整個資源集合進行操作的,如果不寫id就由ES生成一個唯一id進行創建==新文檔,如果填了id那就針對這個id的文檔進行創建/更新
2、PUT只會將json數據都進行替換, POST只會更新相同字段的值
3、PUT與DELETE都是冪等性操作, 即不論操作多少次, 結果都一樣
- 查詢文檔
格式: GET /索引名稱/類型/id 舉例: GET /es_db/_doc/1
- 刪除文檔
格式: DELETE /索引名稱/類型/id 舉例: DELETE /es_db/_doc/1
9.Restful認識
Restful是一種面向資源的架構風格,可以簡單理解為:使用URL定位資源,用HTTP動詞(GET,POST,DELETE,PUT)描述操作。 基于Restful API ES和所有客戶端的交互都是使用JSON格式的數據.
其他所有程序語言都可以使用RESTful API,通過9200端口的與ES進行通信
GET查詢、PUT添加、POST修改、DELE刪除
使用Restful的好處:
透明性,暴露資源存在。
充分利用 HTTP 協議本身語義,不同請求方式進行不同的操作
10.查詢操作
10.1 查詢當前類型中的所有文檔 _search
格式: GET /索引名稱/類型/_search
舉例: GET /es_db/_doc/_search SQL: select * from student
10.2 條件查詢, 如要查詢age等于28歲的 _search?q=:**
格式: GET /索引名稱/類型/_search?q=:** 舉例: GET /es_db/_doc/_search?q=age:28
10.3 范圍查詢, 如要查詢age在25至26歲之間的 _search?q=*[ TO **] 注意: TO 必須為大寫
格式: GET /索引名稱/類型/_search?q=***[25 TO 26] 舉例: GET /es_db/_doc/_search?q=age[25 TO 26]
10.4 根據多個ID進行批量查詢 _mget
格式: GET /索引名稱/類型/_mget 舉例: GET /es_db/_doc/_mget
10.5 查詢年齡小于等于28歲的 :<=
格式: GET /索引名稱/類型/_search?q=age:<=** 舉例: GET /es_db/_doc/_search?q=age:<=28
10.6 查詢年齡大于28前的 :>
格式: GET /索引名稱/類型/_search?q=age:>** 舉例: GET /es_db/_doc/_search?q=age:>28
10.7 分頁查詢 from=&size=
格式: 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
10.8 對查詢結果只輸出某些字段 _source=字段,字段
格式: GET /索引名稱/類型/_search?_source=字段,字段 舉例: GET /es_db/_doc/_search?_source=name,age
10.9 對查詢結果排序 sort=字段:desc/asc
格式: GET /索引名稱/類型/_search?sort=字段 desc 舉例: GET /es_db/_doc/_search?sort=age:desc