ELK入門及基本使用

預備知識-Restful

起源html

  在沒有先後端分離概念以前,一個網站的完成老是「all in one」,在這個階段,頁面、數據、渲染所有在服務端完成,這樣作的最大的弊端是後期維護,擴展極其痛苦,開發人員必須同時具有先後端知識。因而後來慢慢的興起了先後端分離的思想:即後端負責數據編造,而前端則負責數據渲染,前端靜態頁面調用指定 api 獲取到有固定格式的數據,再將數據展現出來,這樣呈現給用戶的就是一個」動態「的過程。前端

  而關於 api 這部分的設計則成了一個問題。如何設計出一個便於理解,容易使用的 api 則成了一個問題,而所謂的 RESTful 就是用來規範咱們的 API 的一種約束。java

REST

  做爲 REST,實際上是 Representational State Transfer(表象層狀態轉變)三個單詞的縮寫,它由 Roy Fielding(Fielding 是 HTTP 協議(1.0 版和 1.1 版)的主要設計者、Apache 服務器軟件的做者之1、Apache 基金會的第一任主席)於2000 年論文中提出,他在論文中提到:"我這篇文章的寫做目的,就是想在符合架構原理的前提下,理解和評估以網絡爲基礎的應用軟件的架構設計,獲得一個功能強、性能好、適宜通訊的架構。REST 指的是一組架構約束條件和原則。"若是一個架構符合 REST 的約束條件和原則,咱們就稱它爲 RESTful 架構。node

  要理解 RESTful 架構,最好的方法就是去理解 Representational StateTransfer 這個詞組究竟是什麼意思,它的每個詞表明瞭什麼涵義。若是你把這個名稱搞懂了,也就不難體會 REST 是一種什麼樣的設計。linux

資源(Resources)git

REST 的名稱"表現層狀態轉化"中,省略了主語。"表現層"其實指的是"資源"(Resources)的"表現層"。github

所謂"資源",就是網絡上的一個實體,或者說是網絡上的一個具體信息。它能夠是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的實在。算法

要讓一個資源能夠被識別,須要有個惟一標識,在 Web 中這個惟一標識就是URI(Uniform Resource Identifier)。數據庫

URI 既能夠當作是資源的地址,也能夠當作是資源的名稱。若是某些信息沒有使用 URI 來表示,那它就不能算是一個資源,只能算是資源的一些信息而已。編程

你能夠用一個 URI(統一資源定位符)指向它,每種資源對應一個特定的 URI。

要獲取這個資源,訪問它的 URI 就能夠,所以 URI 就成了每個資源的地址或獨一無二的識別符。

所謂"上網",就是與互聯網上一系列的"資源"互動,調用它的 URI。

 

URI 設計技巧

一、使用 _ 或 - 來讓 URI 可讀性更好

曾經 Web 上的 URI 都是冰冷的數字或者無心義的字符串,但如今愈來愈多的網站使用_或-來分隔一些單詞,讓 URI 看上去更爲人性化。例如國內比較出名的開源中國社區,它上面的新聞地址就採用這種風格,如

 

二、使用 / 來表示資源的層級關係

例如上述/git/git/commit/e3af72cdafab5993d18fae056f87e1d675913d08就表示了一個多級的資源,指的是 git 用戶的 git 項目的某次提交記錄,又例如/orders/2012/10 能夠用來表示 2012 年 10 月的訂單記錄。

三、使用 ? 用來過濾資源

不少人只是把?簡單的當作是參數的傳遞,很容易形成 URI 過於複雜、難以理解。能夠把?用於對資源的過濾,例如/git/git/pulls 用來表示 git 項目的全部推入請求,而/pulls?state=closed 用來表示 git 項目中已經關閉的推入請求,這種 URL 一般對應的是一些特定條件的查詢結果或算法運算結果。

, 或; 能夠用來表示同級資源的關係

有時候咱們須要表示同級資源的關係時,能夠使用,或;來進行分割。例如哪天github 能夠比較某個文件在隨意兩次提交記錄之間的差別,或許能夠使用/git/git

/block-sha1/sha1.h/compare/e3af72cdafab5993d18fae056f87e1d675913d08;bd63e61bdf38e872d5215c07b264dcc16e4febca 做爲 URI。不過,如今 github 是使用…來作這個事情的,例如/git/git/compare/master…next。

四、URI 不該該包含動詞

由於"資源"表示一種實體,因此應該是名詞,URI 不該該有動詞,動詞應該放在 HTTP 協議中。

舉例來講,某個 URI 是/posts/show/1,其中 show 是動詞,這個 URI 就設計錯了,正確的寫法應該是/posts/1,而後用 GET 方法表示 show。

若是某些動做是 HTTP 動詞表示不了的,你就應該把動做作成一種資源。好比網上匯款,從帳戶 1向帳戶 2匯款 500 元,錯誤的 URI 是:

POST /accounts/1/transfer/500/to/2

正確的寫法是把動詞 transfer 改爲名詞 transaction,資源不能是動詞,可是能夠是一種服務。

五、URI 中不宜加入版本號

例如:

http://www.example.com/app/1.0/foo

http://www.example.com/app/1.1/foo

http://www.example.com/app/2.0/foo

 

由於不一樣的版本,能夠理解成同一種資源的不一樣表現形式,因此應該採用同一個 URI。版本號能夠在 HTTP 請求頭信息的 Accept 字段中進行區分。

 

表現層(Representation)

  "資源"是一種信息實體,它能夠有多種外在表現形式。咱們把"資源"具體呈現出來的形式,叫作它的"表現層"(Representation)。

好比,文本能夠用 txt 格式表現,也能夠用 HTML 格式、XML 格式、JSON 格式表現,甚至能夠採用二進制格式;圖片能夠用 JPG 格式表現,也能夠用 PNG格式表現。

URI 只表明資源的實體,不表明它的形式。嚴格地說,有些網址最後的".html"後綴名是沒必要要的,由於這個後綴名錶示格式,屬於"表現層"範疇,而URI 應該只表明"資源"的位置。它的具體表現形式,應該在 HTTP 請求的頭信息中用 Accept 和 Content-Type 字段指定,這兩個字段纔是對"表現層"的描述。

 

狀態轉化(State Transfer)

  訪問一個網站,就表明了客戶端和服務器的一個互動過程。在這個過程當中,勢必涉及到數據和狀態的變化。

互聯網通訊協議 HTTP 協議,是一個無狀態協議。這意味着,全部的狀態都保存在服務器端。所以,若是客戶端想要操做服務器,必須經過某種手段,讓服務器端發生"狀態轉化"(State Transfer)。而這種轉化是創建在表現層之上的,因此就是"表現層狀態轉化"。

客戶端用到的手段,目前來講只能是 HTTP 協議。具體來講,就是 HTTP 協議裏面,四個表示操做方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操做:GET 用來獲取資源,POST 用來新建資源(也能夠用於更新資源),PUT用來更新資源,DELETE 用來刪除資源。GET、PUT 和 DELETE 請求都是冪等的,不管對資源操做多少次,結果老是同樣的, POST 不是冪等的。

 

什麼是 RESTful 架構

  綜合上面的解釋,咱們總結一下什麼是 RESTful 架構:

  1.架構裏,每個 URI 表明一種資源;

  2.客戶端和服務器之間,傳遞這種資源的某種表現層;

  3.客戶端經過四個 HTTP 動詞(get、post、put、delete),對服務器端資源進行操做,實現」表現層狀態轉化」。

  注意:REST 架構風格並非綁定在 HTTP 上,只不過目前 HTTP 是惟一與 REST相關的實例。因此咱們這裏描述的 REST 也是經過 HTTP 實現的 REST。

 

辨析 URI、URL、URN

RFC 3986 中是這樣說的:

A Uniform Resource Identifier (URI) 是一個緊湊的字符串用來標示抽象或物理資源。一個 URI 能夠進一步被分爲定位符、名字或二者都是. 術語「Uniform Resource Locator」(URL) 是 URI 的子集, 除了肯定一個資源,還提供一種定位該資源的主要訪問機制。

因此,URI = Universal Resource Identifier 統一資源標誌符,包含 URL和URN,支持的協議有 http、https、ftp、mailto、magnet、telnet、data、file、nfs、gopher、ldap 等,java 還大量使用了一些非標準的定製模式,如 rmi,jar、jndi 和 doc,來實現各類不一樣用途。

URL = Universal Resource Locator 統一資源定位符,URL 惟一地標識一個資源在 Internet 上的位置。無論用什麼方法表示,只要能定位一個資源,就叫URL。

URN = Universal Resource Name 統一資源名稱,URN 它命名資源但不指定如何定位資源,好比:只告訴你一我的的姓名,不告訴你這我的在哪。

對於一個資源來講,URN 就比如他的名字,而 URL 就比如是資源的街道住址。

換句話說,URN 標識了一個資源項目,而 URL 則提供了一種找到他的方法。

好比同時指定基本的獲取機制和網絡位置。舉個例子,

http://example.org/wiki/Main_Page,指向了一個被識別爲/wike/Main_Page的資源,這個資源的表現形式是 HTML 和相關的代碼。而獲取這個資源的方法是在網絡中從一個名爲 example.org 的主機上,經過 HTTP( Hypertext TransferProtocol)得到。

而 URN 則是一種在特定的名稱空間中經過經過名字來標識資源的 URI。當討論一種資源而不須要知道它的位置或者如何去得到它的時候,就能夠使用 URN。

例如,在 International Standard Book Number (ISBN)系統中,* ISBN

0-486-27557-4 用來指定莎士比亞的做品《羅密歐與朱麗葉》的一個特定版本。

指示這一版本的 URN 是 urn:isbn:0-486-27557-4*,可是若是想要得到這個版本的書,就須要知道它的位置,這樣就必須知道它的 URL。

 

什麼是 ELK

爲何須要 ELK

官網的說法:Elasticsearch 是一個開源的分佈式 RESTful 搜索和分析引擎,可以解決愈來愈多不一樣的應用場景。

看一個應用場景,常見的 WEB 應用日誌分析。通常咱們會怎麼作?

登陸到每臺服務器上,直接在日誌文件中 grep、awk 就能夠得到本身想要的信息。但在規模較大的場景中,此方法效率低下,面臨問題包括日誌量太大如何歸檔、文本搜索太慢怎麼辦、如何多維度查詢。

這個時候咱們但願集中化的日誌管理,全部服務器上的日誌收集彙總。常看法決思路是創建集中式日誌收集系統,將全部節點上的日誌統一收集,管理,訪問。

這樣對於大型系統來講,都是一個分佈式部署的架構,不一樣的服務模塊部署在不一樣的服務器上,問題出現時,大部分狀況須要根據問題暴露的關鍵信息,定位到具體的服務器和服務模塊,構建一套集中式日誌系統,能夠提升定位問題的效率。

一個完整的集中式日誌系統,須要包含如下幾個主要特色:

收集-可以採集多種來源的日誌數據

傳輸-可以穩定的把日誌數據傳輸到中央系統

存儲-如何存儲日誌數據分析-能夠支持

UI 分析警告-可以提供錯誤報告,監控機制

ELK就是這樣一整套解決方案,而且都是開源軟件,之間互相配合使用,完美銜接,高效的知足了不少場合的應用,而不只僅是日誌分析。

什麼是 ELK

ELK是三個開源軟件的縮寫,分別表示:Elasticsearch , Logstash, Kibana , 它們都是開源軟件。

Elasticsearch是個開源分佈式搜索引擎,提供蒐集、分析、存儲數據三大功能。它的特色有:分佈式,零配置,自動發現,索引自動分片,索引副本機制,restful風格接口,多數據源,自動搜索負載等。

Logstash 主要是用來日誌的蒐集、分析、過濾日誌的工具,支持大量的數據獲取方式。通常工做方式爲 c/s 架構,client端安裝在須要收集日誌的主機上,server端負責將收到的各節點日誌進行過濾、修改等操做在一併發往 elasticsearch上去。

Kibana 也是一個開源和免費的工具,Kibana 能夠爲 Logstash 和

ElasticSearch 提供的日誌分析友好的 Web 界面,能夠幫助彙總、分析和搜索重要數據日誌。

新增了一個 Beats 系列組件,它是一個輕量級的日誌收集處理工具(Agent),Beats 佔用資源少,適合於在各個服務器上搜集日誌或信息後傳輸給 Logstash。

加入 Beats 系列組件後,官方名稱就變爲了 Elastic Stack,產品以下:

安裝,啓動和 HelloWorld

環境和安裝

運行環境爲 Linux,演示服務器操做系統版本狀況以下:

 

由於 Elastic Stack中主要組件都是用 Java 寫的,因此操做系統上還應該安裝好 Java,本次以 Elasticsearch 7 版本爲主,因此,須要安裝 JDK1.8 以上。

 

而 Elastic Stack系列產品咱們能夠到 Elastic的官網上去下載:

https://www.elastic.co/cn/downloads

 

選擇 7.7.0版本爲本次版本,從具體的下載頁面能夠看到 Elastic Stack支持各類形式的安裝。

 

 

選擇以避免安裝的壓縮包的形式。下載後上傳到服務器解壓縮便可運行。

 

運行

  Elasticsearch 默認不容許用 root用戶運行,會報錯,並且從服務器安全的角度來講,也不該該以 root用戶來作平常工做,所以咱們新建一個用戶 elk並以elk用戶登陸。

Elasticsearch

  用 tar -xvf命令解壓壓縮包elasticsearch-7.7.0-linux-x86_64.tar.gzip後進入elasticsearch-7.7.0文件夾中的 bin文件夾,並執行命令./elasticsearch。

待啓動完成.....

 

 

 

 

輸入 curl http://localhost:9200

顯示:

表示Elasticsearch運行成功了,咱們試着在本地瀏覽器進行訪問

 

 

 

 

卻顯示「拒絕了咱們的鏈接請求」,所以咱們還須要配置一下 Elasticsearch以容許咱們進行外網訪問,進入 elasticsearch-7.7.0下的 config目錄,編輯elasticsearch.yml文件,刪除 network.host前的#字符,並寫入服務器的地址並保存。

再次運行,可是此次卻出了錯

從錯誤提示咱們能夠知道,還需對 Elasticsearch配置作適當修改,從新編輯elasticsearch.yml文件,並作以下修改:

 

 

 

再次啓動,並在瀏覽器中訪問

顯示 Elasticsearch運行並訪問成功!

咱們知道,Elasticsearch提供的是 restful風格接口,咱們用瀏覽器訪問不是很方便,除非咱們自行編程訪問 restful接口。這個時候,就能夠用上 Kibana 了,它已經爲咱們提供了友好的 Web 界面,方便咱們後面對 Elasticsearch的學習。

接下來咱們安裝運行 Kibana。

Kibana

一樣用 tar -xvf命令解壓壓縮包,進入解壓後的目錄。爲了方便咱們的訪問和鏈接 Elasticsearch,也須要進入 Kibana的 config 目錄對 Kibana 進行配置。

 

而後進入 Kibana的 bin 目錄運行./kibana,kibana由於是用 node.js 編寫的,因此啓動和運行較慢,須要等待一段時間:

 

 

 

從提示咱們能夠看出,kibana的訪問端口是 5601,咱們依然在本地瀏覽器中訪問:

 

 

 

等候幾分鐘之後,就會進入 kibana的主界面

 

 

 

TIPS:如何檢測系統中是否啓動了 kibana?

咱們通常會用ps -ef來查詢某個應用是否在 Linux系統中啓動,好比Elasticsearch,

咱們用 ps -ef|grep java 或者 ps -ef|grep elasticsearch都可

可是當咱們嘗試 ps -ef|grep kibana,倒是不行的

由於 kibana 是 node 寫的,因此 kibana 運行的時候是運行在 node 裏面,咱們要查詢的話,只能 ps -ef|grep node

或者使用 netstat -tunlp|grep 5601

 

 

 

由於咱們的kibana開放的端口是5601,因此看到5601端口被 Listen (監聽),說明 kibana啓動成功。

附:netstat參數說明:

  -t (tcp)僅顯示 tcp相關選項

  -u (udp)僅顯示 udp相關選項

  -n 拒絕顯示別名,能顯示數字的所有轉化成數字。

  -l 僅列出有在 Listen (監聽) 的服務狀態

  -p 顯示創建相關連接的程序名

更多 netstat的相關說明,自行查閱 Linux手冊

HelloWorld

點擊面板中的「Dev Tools」按鈕,進入 Dev 工具,開始咱們的 Elasticsearch初次訪問之旅。

 

 

 

建立索引

在左邊命令窗口中輸入 put enjoy_test,並點擊相關按鈕 ,因而看到右

邊的結果窗口中 es給咱們返回了處理結果,表示咱們在 es中建立索引成功。

 

 

 

查看索引

要查看咱們剛剛建立的索引,執行「get enjoy_test」

添加文檔

往這個索引中添加文檔,執行:

PUT /enjoy_test/_doc/1

{

"msg":"Hello World!"

}

查看文檔

查詢咱們剛剛加入的文檔,執行「get /enjoy_test/_doc/1」

 

 

 

Elasticsearch 基本原理和概念

 

從上面的例子中,咱們看到了不少熟悉又陌生的概念,好比索引、文檔等等。這些概念和咱們平時看到的數據庫裏的好比索引有什麼區別呢?

舉個例子,如今咱們要保存唐宋詩詞,數據庫中咱們們會怎麼設計?詩詞表咱們可能的設計以下:

朝代

做者

詩詞年代

標題

詩詞全文

李白

 

靜夜思

牀前明月光,疑是地上霜。舉頭望明月,低頭思故鄉。

李清照

 

如夢令

常記溪亭日暮,沉醉不知歸路,興盡晚回舟,誤入藕花深處。爭渡,爭渡,驚起一灘鷗鷺。

….

….

….

…….

要根據朝代或者做者尋找詩,都很簡單,好比「select 詩詞全文 from 詩詞表where做者=‘李白’」,若是數據不少,查詢速度很慢,怎麼辦?咱們能夠在對應的查詢字段上創建索引加速查詢。

可是若是咱們如今有個需求:要求找到包含「望」字的詩詞怎麼辦?用

「select 詩詞全文 from 詩詞表 where 詩詞全文 like‘%望%’」,這個意味着

要掃描庫中的詩詞全文字段,逐條比對,找出全部包含關鍵詞「望」字的記錄,。

基本上,數據庫中通常的 SQL 優化手段都是用不上的。數量少,大概性能還能接受,若是數據量稍微大點,就徹底沒法接受了,更況且在互聯網這種海量數據的狀況下呢?

怎麼解決這個問題呢,用倒排索引。

倒排索引 Inverted index

好比如今有:

  蜀道難(唐)李白 蜀道之難難於上青天,側身西望長諮嗟。

  靜夜思(唐)李白 舉頭望明月,低頭思故鄉。

  春臺望(唐)李隆基 暇景屬三春,高臺聊四望。

  鶴沖天(宋)柳永 黃金榜上,偶失龍頭望。明代暫遺賢,如何向?未遂風雲便,爭不恣狂蕩。何必論得喪?才子詞人,自是白衣卿相。煙花巷陌,依約丹青屏障。

  幸有意中人,堪尋訪。且恁偎紅翠,風流事,生平暢。青春都一餉。忍把浮名,換了淺斟低唱!

都有望字,因而咱們能夠這麼保存

序號

關鍵字

蜀道難

靜夜思

春臺望

鶴沖天

1

 

 

 

 

 

 

若是查哪一個詩詞中包含上,怎麼辦,上述的表格能夠繼續填入新的記錄

序號

關鍵字

蜀道難

靜夜思

春臺望

鶴沖天

1

2

 

 

其實,上述詩詞的中每一個字均可以做爲關鍵字,而後創建關鍵字和文檔之間的對應關係,也就是標識關鍵字被哪些文檔包含。

因此,倒排索引就是,將文檔中包含的關鍵字所有提取處理,而後再將關鍵字和文檔之間的對應關係保存起來,最後再對關鍵字自己作索引排序。用戶在檢索某一個關鍵字是,先對關鍵字的索引進行查找,再經過關鍵字與文檔的對應關係找到所在文檔。

在存儲在關係型數據庫中的數據,須要咱們事先分析將數據拆分爲不一樣的字段,而在 es 這類的存儲中,須要應用程序根據規則自動提取關鍵字,並造成對應關係。

這些預先提取的關鍵字,在全文檢索領域通常被稱爲 term(詞項),文檔的詞項提取在 es 中被稱爲文檔分析,這是全文檢索很核心的過程,必需要區分哪些是詞項,哪些不是,好比不少場景下,apple和 apples 是同一個東西,望和看實際上是同一個動做。

Elasticsearch 基本概念

Elasticsearch 中比較關鍵的基本概念有索引、文檔、映射、映射類型、文檔字段概念,爲了方便理解,能夠和關係數據庫中的相關概念進行個比對:

Elasticsearch 索引

  Elasticsearch 索引是映射類型的容器。一個 Elasticsearch 索引很是像關係型世界的數據庫,是獨立的大量文檔集合。

  固然在底層,確定用到了倒排索引,最基本的結構就是「keyword」和「PostingList」,Posting list就是一個 int的數組,存儲了全部符合某個 term的文檔 id。

  另外,這個倒排索引相比特定詞項出現過的文檔列表,會包含更多其它信息。

  它會保存每個詞項出現過的文檔總數,在對應的文檔中一個具體詞項出現的總次數,詞項在文檔中的順序,每一個文檔的長度,全部文檔的平均長度等等相關信息。

文檔 (Document)

  文檔是 es 中全部可搜索數據的最小單位,好比日誌文件中的日誌項、一部電影的具體信息等等。

  文檔會被序列化 JSON格式保存到 ElasticSearch 中,JSON 對象由字段組成,每一個字段都有對象的字段類型(字符串,數值,布爾,日期,二進制,範圍類型)。

  同時每一個文檔都有一個 Unique ID,能夠本身指定 ID,或者經過 ElasticSearch 自動生成。

  因此嚴格來講,es 中存儲的文檔是一種半結構化的數據。

映射

  映射(mapping)定義了每一個字段的類型、字段所使用的分詞器等。

  get /enjoy_test/_mapping

能夠顯式映射,由咱們在索引映射中進行預先定義;也能夠動態映射,在添加文檔的時候,由 es 自動添加到索引,這個過程不須要事先在索引進行字段數據類型匹配等等,es 會本身推斷數據類型。

既然說到了字段類型,固然就離不開字段的數據類型了。

文檔字段

文檔中的一個字段 field就至關於關係型數據庫中的一列 column,那麼它確定有數據類型,es 提供的數據類型包括至少有:

數據類型

核心數據類型

# 字符串類型:string,字符串類還可被分爲 text和 keyword 類型,若是咱們讓 es自動映射數據,那麼 es 會把字符串定義爲 text,而且還加了一個 keyword類型字段。

text文本數據類型,用於索引全文值的字段。使用文本數據類型的字段,它們會被分詞,在索引以前將字符串轉換爲單個術語的列表(倒排索引),分詞過程容許 ES 搜索每一個全文字段中的單個單詞。什麼狀況適合使用 text,只要不具有惟一性的字符串通常均可以使用 text。

keyword,關鍵字數據類型,用於索引結構化內容的字段。使用 keyword 類型的字段,其不會被分析,給什麼值就原封不動地按照這個值索引,因此關鍵字字段只能按其確切值進行搜索。什麼狀況下使用 keyword,具備惟一性的字符串,例如:電子郵件地址、MAC 地址、身份證號、狀態代碼...等等。

# 數字型數據類型:long、integer、short、byte、double、float

# 日期類型:date

# 布爾類型:boolean

複雜數據類型

# 數組:無需專門的數據類型

# 對象數據類型:單獨的 JSON對象

# 嵌套數據類型:nested,關於 JSON對象的數組

地理數據類型:

# 地理點數據類型

# 地理形狀數據類型

專門數據類型:

# IPv4 數據類型

# 單詞計數數據類型 token_count

咱們結合前面的映射來看看:

建立一個新的索引:put /open-soft

顯式映射:

put /open-soft/_mapping

{

"properties" : {

"corp" : {

"type" : "text"

},

"lang" : {

"type" : "text"

},

"name" : {

"type" : "text"

}

 

索引或者說入庫一個文檔,注意這個文檔的字段,比咱們顯示映射的字段要多個 star字段:

put /open-soft/_doc/1

{

"name": "Apache Hadoop",

"lang": "Java",

"corp": "Apache",

"stars":200

}

經過 get /open-soft/_mapping,咱們能夠看到 es 自動幫咱們新增了 stars這個字段。

修改映射,增長一個新的字段:

put /open-soft/_mapping

{

"properties" : {

"year" : {

"type" : "integer"

}

}

}

數組

  不須要特殊配置,一個字段若是被配置爲基本數據類型,就是天生支持數組類型的。任何字段均可以有 0個或多個值,可是在一個數組中數據類型必須同樣。

好比:

put /open-soft/_doc/2

{

"name": ["Apache Activemq","Activemq Artemis"],

"lang": "Java",

"corp": "Apache",

"stars":[500,200]

}

是沒問題的,可是若是:

put /open-soft/_doc/3

{

"name": ["Apache Kafka"],

"lang": "Java",

"corp": "Apache",

"stars":[500,"kafka"]

}

則會出錯。

對象

JSON文檔是有層次結構的,一個文檔可能包含其餘文檔,若是一個文檔包含其餘文檔,那麼該文檔值是對象類型,其數據類型是對象。固然 ElasticSearch中是沒有所謂對象類型的,好比:

put /open-soft/_doc/object

{

"name": ["Apache ShardingSphere"],

"lang": "Java",

"corp": "JingDong",

"stars":400,

"address":{

"city":"BeiJing",

"country":"亦莊"

}

}

對象類型能夠在定義索引的映射關係時進行指定。

多數據類型

  若是說數組容許你使用同一個設置索引多項數據,那麼多數據類型容許使用不一樣的設置,對同一項數據索引屢次。帶來的好處就是能夠同一文本有多種不一樣的索引方式,好比一個字符串類型的字段,能夠使用 text類型作全文檢索,使用keyword 類型作聚合和排序。咱們能夠看到 es 的動態映射生成的字段類型裏,每每字符串類型都使用了多數據類型。固然,咱們同樣也能夠本身定義:

put /open-soft/_mapping

{

"properties" : {

"name" : {

"type" : "text",

"fields":{

"raw":{

"type" : "keyword"

},

"length":{

"type" : "token_count",

"analyzer":"standard"

}

}

}

}

}

  在上面的代碼裏,咱們使用"fields"就把 name字段擴充爲多字段類型,爲name新增了兩個子字段 raw和 length,raw設置類型爲 keyword,length 設置類型爲 token_count,告訴 es 這個字段在保存還須要作詞頻統計。

  經過 fields字段設置的子字段 raw 和 length,在咱們添加文檔時,並不須要單獨設置值,他們 name共享相同的值,只是 es 會以不一樣的方式處理字段值。

  一樣在檢索文檔的時候,它們也不會顯示在結果中,因此它們通常都是在檢索中以查詢條件的形式出現,以減小檢索時的性能開銷。

字段參數 

 在上面的代碼裏出現了analyzer這個詞,這是什麼?這個叫字段參數,和 type同樣,能夠用來對字段進行配置。經常使用的字段參數和做用以下:

analyzer

  指定分詞器。elasticsearch是一款支持全文檢索的分佈式存儲系統,對於 text類型的字段,首先會使用分詞器進行分詞,而後將分詞後的詞根一個一個存儲在倒排索引中,後續查詢主要是針對詞根的搜索。

analyzer該參數能夠在每一個查詢、每一個字段、每一個索引中使用,其優先級以下(越靠前越優先):

  一、字段上定義的分詞器

  二、索引配置中定義的分詞器

  三、默認分詞器(standard)

 

normalizer

  規範化,主要針對 keyword 類型,在索引該字段或查詢字段以前,能夠先對原始數據進行一些簡單的處理,而後再將處理後的結果當成一個詞根存入倒排索引中,默認爲 null,好比:

PUT index

{

"settings": {

"analysis": {

"normalizer": {

"my_normalizer": { // 1

"type": "custom",

"char_filter": [],

"filter": ["lowercase", "asciifolding"] // 2

}

}

}

},

"mappings": {

"_doc": {

"properties": {

"foo": {

"type": "keyword",

"normalizer": "my_normalizer" // 3

}

}

}

}

}

代碼 1:首先在 settings中的 analysis 屬性中定義 normalizer。

代碼 2:設置標準化過濾器,示例中的處理器爲小寫、asciifolding。

代碼 3:在定義映射時,若是字段類型爲 keyword,能夠使用 normalizer

引用定義好的 normalizer

 

boost

權重值,能夠提高在查詢時的權重,對查詢相關性有直接的影響,其默認值爲1.0。其影響範圍爲詞根查詢(team query),對前綴、範圍查詢。5.0 版本後已廢止。

 

coerce

數據不老是咱們想要的,因爲在轉換 JSON body 爲真正 JSON 的時候,整型數字5有可能會被寫成字符串"5"或者浮點數 5.0,這個參數能夠將數值不合法的部分去除。默認爲 true。

例如:將字符串會被強制轉換爲整數、浮點數被強制轉換爲整數。

例如存在以下字段類型:

"number_one": {

"type": "integer"

}

聲明 number_one字段的類型爲數字類型,那是否容許接收「6」字符串形式的數據呢?由於在 JSON中,「6」用來賦給 int類型的字段,也是能接受的,默認 coerce 爲 true,表示容許這種賦值,但若是 coerce 設置爲 false,此時 es只能接受不帶雙引號的數字,若是在 coerce=false 時,將「6」賦值給 number_one時會拋出類型不匹配異常。

 

copy_to

copy_to參數容許您建立自定義的_all字段。換句話說,多個字段的值能夠複製到一個字段中。

例如,first_name和 last_name 字段能夠複製到 full_name 字段以下:

PUT my_index

{

"mappings": {

"_doc": {

"properties": {

"first_name": {

"type": "text",

"copy_to": "full_name"

},

"last_name": {

"type": "text",

"copy_to": "full_name"

 

表示字段 full_name的值來自 first_name + last_name。

關於 copy_to重點說明:

一、字段的複製是原始值。

二、同一個字段能夠複製到多個字段,寫法以下:「copy_to」: [ 「field_1」,

「field_2」]

doc_values

  Doc values 的存在是由於倒排索引只對某些操做是高效的。倒排索引的優點在於查找包含某個項的文檔,而對於從另一個方向的相反操做並不高效,即:肯定哪些項是否存在單個文檔裏,聚合須要這種次級的訪問模式。

  對於如下倒排索引:

  若是咱們想要得到全部包含 檔的詞的完整列表,倒排索引是根據項來排序的,因此咱們首先在詞 ,而後掃描全部列,找到包含 brown 的文檔。咱們能夠快速 和 包含 brown 這個 token。

  而後,對於聚合部分,咱們須要找到 Doc_1 和 Doc_2 裏全部惟一的詞項。用倒排索引作這件事情代價很高:咱們會迭代索引裏的每一個詞項並收集 Doc_1 和 Doc_2 列裏面 token。這很慢並且難以擴展:隨着詞項和文檔的數量增長,執行時間也會增長。

  Doc values 經過轉置二者間的關係來解決這個問題。倒排索引將詞項映射到包含它們的文檔,doc values 將文檔映射到它們包含的詞項:

當數據被轉置以後,想要收集到 Doc_1 和 Doc_2 的惟一 token 會很是容易。得到每一個文檔行,獲取全部的詞項,而後求兩個集合的並集。

doc_values缺省是 true,便是開啓的,而且只適用於非 text類型的字段。

dynamic

  是否容許動態的隱式增長字段。在執行 index api 或更新文檔 API 時,對於_source字段中包含一些原先未定義的字段採起的措施,根據 dynamic 的取值,會進行不一樣的操做:

  true,默認值,表示新的字段會加入到類型映射中。

  false,新的字段會被忽略,即不會存入_souce字段中,即不會存儲新字段,也沒法經過新字段進行查詢。

  strict,會顯示拋出異常,須要新使用 put mapping api 先顯示增長字段映射。

enabled

  是否創建索引,默認狀況下爲 true,es 會嘗試爲你索引全部的字段,但有時候某些類型的字段,無需創建索引,只是用來存儲數據便可。也就是說,

ELasticseaech默認會索引全部的字段,enabled設爲 false的字段,elasicsearch 會跳過字段內容,該字段只能從_source 中獲取,可是不可搜。只有映射類型(type)和object 類型的字段能夠設置 enabled屬性。

eager_global_ordinals

  表示是否提早加載全局順序號。Global ordinals 是一個創建在 doc values 和fielddata基礎上的數據結構, 它爲每個精確詞按照字母順序維護遞增的編號。每個精確詞都有一個獨一無二的編號 而且 精確詞 A 小於精確詞 B 的編號.Global ordinals 只支持 keyword 和 text 型字段,在 keyword 字段中, 默認是啓用的 而在 text 型字段中 只有 fielddata 和相關屬性開啓的狀態下才是可用的。

fielddata

  爲了解決排序與聚合,elasticsearch 提供了 doc_values 屬性來支持列式存儲,但doc_values 不支持 text 字段類型。由於 text 字段是須要先分析(分詞),會影響 doc_values 列式存儲的性能。

  es 爲了支持 text字段高效排序與聚合,引入了一種新的數據結構(fielddata),使用內存進行存儲。默認構建時機爲第一次聚合查詢、排序操做時構建,主要存儲倒排索引中的詞根與文檔的映射關係,聚合,排序操做在內存中執行。所以fielddata須要消耗大量的 JVM 堆內存。一旦 fielddata加載到內存後,它將永久存在。

  一般狀況下,加載 fielddata 是一個昂貴的操做,故默認狀況下,text 字段的字段默認是不開啓 fielddata機制。在使用 fielddata 以前請慎重考慮爲何要開啓fielddata。

format

  在 JSON文檔中,日期表示爲字符串。Elasticsearch 使用一組預先配置的格式來識別和解析這些字符串,並將其解析爲 long類型的數值(毫秒),支持自定義格式,也有內置格式。

好比:

 

PUT my_index

{

"mappings": {

"_doc": {

"properties": {

"date": {

"type": "date",

"format": "yyyy-MM-dd HH:mm:ss"

}}}}}

elasticsearch爲咱們內置了大量的格式,以下:

epoch_millis

時間戳,單位,毫秒,範圍受限於 Java Long.MIN_VALUE和 Long.MAX_VALUE。

epoch_second

時間戳,單位,秒,範圍受限於 Java的限制 Long.MIN_VALUE 並 Long.

MAX_VALUE 除以 1000(一秒中的毫秒數)。

date_optional_time或者 strict_date_optional_time

日期必填,時間可選,其支持的格式以下:

date-opt-time = date-element ['T' [time-element] [offset]]

date-element = std-date-element | ord-date-element | week-date-element

std-date-element = yyyy ['-' MM ['-' dd]]

ord-date-element = yyyy ['-' DDD]

week-date-element = xxxx '-W' ww ['-' e]

time-element = HH [minute-element] | [fraction]

minute-element = ':' mm [second-element] | [fraction]

second-element = ':' ss [fraction]

好比"yyyy-MM-dd"、"yyyyMMdd"、"yyyyMMddHHmmss"、

"yyyy-MM-ddTHH:mm:ss"、"yyyy-MM-ddTHH:mm:ss.SSS"、

"yyyy-MM-ddTHH:mm:ss.SSSZ"格式,不支持經常使用的"yyyy-MM-dd HH:mm:ss"等格式。

 

注意,"T"和"Z"是固定的字符。

tips:若是看到「strict_」前綴的日期格式要求,表示 date_optional_time 的嚴格級別,這個嚴格指的是年份、月份、天必須分別以 4位、2 位、2 位表示,不足兩位的話第一位需用 0補齊。

   basic_date

其格式表達式爲 :yyyyMMdd

basic_date_time

其格式表達式爲:yyyyMMdd’T’HHmmss.SSSZ

basic_date_time_no_millis

其格式表達式爲:yyyyMMdd’T’HHmmssZ

basic_ordinal_date

4位數的年 + 3 位(day of year),其格式字符串爲 yyyyDDD

basic_ordinal_date_time

其格式字符串爲 yyyyDDD’T’HHmmss.SSSZ

basic_ordinal_date_time_no_millis

其格式字符串爲 yyyyDDD’T’HHmmssZ

basic_time

其格式字符串爲 HHmmss.SSSZ

basic_time_no_millis

其格式字符串爲 HHmmssZ

basic_t_time

其格式字符串爲’T’HHmmss.SSSZ

basic_t_time_no_millis

其格式字符串爲’T’HHmmssZ

basic_week_date

其格式字符串爲 xxxx’W’wwe,4 爲年 ,而後用’W’, 2 位 week of year(所在年裏周序號)1位 day of week。

basic_week_date_time

其格式字符串爲 xxxx’W’wwe’T’HH:mm:ss.SSSZ.

basic_week_date_time_no_millis

其格式字符串爲 xxxx’W’wwe’T’HH:mm:ssZ.

date

其格式字符串爲 yyyy-MM-dd

date_hour

其格式字符串爲 yyyy-MM-dd’T’HH

date_hour_minute

其格式字符串爲 yyyy-MM-dd’T’HH:mm

date_hour_minute_second

其格式字符串爲 yyyy-MM-dd’T’HH:mm:ss

date_hour_minute_second_fraction

其格式字符串爲 yyyy-MM-dd’T’HH:mm:ss.SSS

date_hour_minute_second_millis

其格式字符串爲 yyyy-MM-dd’T’HH:mm:ss.SSS

date_time

其格式字符串爲 yyyy-MM-dd’T’HH:mm:ss.SSS

date_time_no_millis

其格式字符串爲 yyyy-MM-dd’T’HH:mm:ss

hour

其格式字符串爲 HH

hour_minute

其格式字符串爲 HH:mm

hour_minute_second

其格式字符串爲 HH:mm:ss

hour_minute_second_fraction

其格式字符串爲 HH:mm:ss.SSS

hour_minute_second_millis

其格式字符串爲 HH:mm:ss.SSS

ordinal_date

其格式字符串爲 yyyy-DDD,其中 DDD爲 day of year。

ordinal_date_time

其格式字符串爲 yyyy-DDD‘T’HH:mm:ss.SSSZZ,其中 DDD爲 day of year。

ordinal_date_time_no_millis

其格式字符串爲 yyyy-DDD‘T’HH:mm:ssZZ

time

其格式字符串爲 HH:mm:ss.SSSZZ

time_no_millis

其格式字符串爲 HH:mm:ssZZ

t_time

其格式字符串爲’T’HH:mm:ss.SSSZZ

t_time_no_millis

其格式字符串爲’T’HH:mm:ssZZ

week_date

其格式字符串爲 xxxx-'W’ww-e,4 位年份,ww 表示 week of year,e 表示 dayof week。

week_date_time

其格式字符串爲 xxxx-'W’ww-e’T’HH:mm:ss.SSSZZ

week_date_time_no_millis

其格式字符串爲 xxxx-'W’ww-e’T’HH:mm:ssZZ

weekyear

其格式字符串爲 xxxx

weekyear_week

其格式字符串爲 xxxx-'W’ww,其中 ww 爲 week of year。

weekyear_week_day

其格式字符串爲 xxxx-'W’ww-e,其中 ww 爲 week of year,e爲 day of week。

year

  其格式字符串爲 yyyy

  year_month

  其格式字符串爲 yyyy-MM

year_month_day

  其格式字符串爲 yyyy-MM-dd

ignore_above

ignore_above用於指定字段索引和存儲的長度最大值,超過最大值的會被忽略。

ignore_malformed

 ignore_malformed能夠忽略不規則數據,對於 login 字段,有人可能填寫的是date類型,也有人填寫的是郵件格式。給一個字段索引不合適的數據類型發生異常,致使整個文檔索引失敗。若是 ignore_malformed參數設爲 true,異常會被忽

略,出異常的字段不會被索引,其它字段正常索引。

   

index

index 屬性指定字段是否索引,不索引也就不可搜索,取值能夠爲 true 或者false,缺省爲 true。

 

index_options

index_options 控制索引時存儲哪些信息到倒排索引中,,用於搜索和突出顯示目的。

docs 只存儲文檔編號

freqs 存儲文檔編號和詞項頻率。

positions 文檔編號、詞項頻率、詞項的位置被存儲

offsets 文檔編號、詞項頻率、詞項的位置、詞項開始和結束的字符位置都被存儲。

 

fields

fields可讓同一文本有多種不一樣的索引方式,好比一個 String 類型的字段,能夠使用 text類型作全文檢索,使用 keyword 類型作聚合和排序。

 

norms

norms參數用於標準化文檔,以便查詢時計算文檔的相關性。norms 雖然對評分有用,可是會消耗較多的磁盤空間,若是不須要對某個字段進行評分,最好不要開啓 norms。

 

null_value

通常來講值爲 null的字段不索引也不能夠搜索,null_value參數可讓值爲null的字段顯式的可索引、可搜索。

PUT my_index

{

"mappings": {

"my_type": {

"properties": {

"status_code": {

"type": "keyword",

"null_value": "NULL"

}

}

}

}

 

}

 

 

 

 

 

 

GET my_index/_search

 

{

 

"query": {

 

"term": {

 

"status_code": "NULL"

 

}

 

}

 

}

 

文檔 1能夠被搜索到,由於 status_code的值爲 null,文檔 2 不能夠被搜索到,由於 status_code爲空數組,可是不是 null。

 

 

 

position_increment_gap

 

文本數組元素之間位置信息添加的額外值。

 

舉例,一個字段的值爲數組類型:"names": [ "John Abraham", "Lincoln Smith"]爲了區別第一個字段和第二個字段,Abraham和 Lincoln在索引中有一個間

 

距,默認是 100。例子以下,這是查詢」Abraham Lincoln」是查不到的:

 

PUT my_index/groups/1

 

{

 

"names": [ "John Abraham", "Lincoln Smith"]

 

}

 

 

 

GET my_index/groups/_search

{

"query": {

"match_phrase": {

"names": {

"query": "Abraham Lincoln"

}}}}

指定間距大於 10 0 能夠查詢到:

GET my_index/groups/_search

{

"query": {

"match_phrase": {

"names": {

"query": "Abraham Lincoln",

"slop": 101

}}}}

想要調整這個值,在 mapping中經過 position_increment_gap 參數指定間距便可。

 

properties

Object或者 nested類型,下面還有嵌套類型,能夠經過 properties 參數指定。

好比:

PUT my_index

{

"mappings": {

"my_type": {

"properties": {

"manager": {

"properties": {

"age": { "type": "integer" },

"name": { "type": "text" }

}

},

"employees": {

"type": "nested",

"properties": {

"age": { "type": "integer" },

"name": { "type": "text" }

}}}}}}

對應的文檔結構:

PUT my_index/my_type/1

{

"region": "US",

"manager": {

"name": "Alice White",

"age": 30

},

"employees": [

{

"name": "John Smith",

"age": 34

},

{

"name": "Peter Brown",

"age": 26

}

]

}

search_analyzer

一般,在索引時和搜索時應用相同的分析器,以確保查詢中的術語與反向索引中的術語具備相同的格式,若是想要在搜索時使用與存儲時不一樣的分詞器,則使用 search_analyzer屬性指定,一般用於 ES 實現即時搜索(edge_ngram)。

 

similarity

指定類似度算法,其可選值:

BM25

當前版本的默認值,使用 BM25算法。

classic

使用 TF/IDF算法,曾經是 es,lucene 的默認類似度算法。

boolean

一個簡單的布爾類似度,當不須要全文排序時使用,而且分數應該只基於查詢條件是否匹配。布爾類似度爲術語提供了一個與它們的查詢boost相等的分數。

 

store

默認狀況下,字段值被索引以使其可搜索,但它們不存儲。這意味着能夠查詢字段,但沒法檢索原始字段值。一般這並不重要。字段值已是_source字段的一部分,該字段默認存儲。若是您只想檢索單個字段或幾個字段的值,而不是整個_source,那麼這能夠經過字段過濾上下文 source filting context來實現。

在某些狀況下,存儲字段是有意義的。例如,若是您有一個包含標題、日期和很是大的內容字段的文檔,您可能只想檢索標題和日期,而不須要從大型_source字段中提取這些字段,能夠將標題和日期字段的 store定義爲 ture。

 

term_vector

Term vectors 包含分析過程產生的索引詞信息,包括:

索引詞列表

每一個索引詞的位置(或順序)

索引詞在原始字符串中的原始位置中的開始和結束位置的偏移量。

term vectors 會被存儲,索引它能夠做爲一個特使的文檔返回。

term_vector可取值:

不存儲 term_vector信息,默認值。

yes

只存儲字段中的值。

with_positions

存儲字段中的值與位置信息。

with_offsets

存儲字段中的值、偏移量

with_positions_offsets

存儲字段中的值、位置、偏移量信息。

 

元字段 meta-fields

一個文檔根據咱們定義的業務字段保存有數據以外,它還包含了元數據字段

(meta-fields)。元字段不須要用戶定義,在任一文檔中都存在,有點相似於數據庫的表結構數據。在名稱上有個顯著的特徵,都是如下劃線「_」開頭。

咱們能夠看看:get /open-soft/_doc/1

大致分爲五種類型:身份(標識)元數據、索引元數據、文檔元數據、路由元數據以及其餘類型的元數據,固然不是每一個文檔這些元字段都有的。

身份(標識)元數據

_index:文檔所屬索引 , 自動被索引,可被查詢,聚合,排序使用,或者腳本里訪問

_type:文檔所屬類型,自動被索引,可被查詢,聚合,排序使用,或者腳本里訪問

_id:文檔的惟一標識,建索引時候傳入 ,不被索引,可經過_uid被查詢,腳本里使用,不能參與聚合或排序

_uid:由_type和_id字段組成,自動被索引 ,可被查詢,聚合,排序使用,或者腳本里訪問,6.0.0版本後已廢止。

 

索引元數據

_all:自動組合全部的字段值,以空格分割,能夠指定分器詞索引,可是整個值不被存儲,因此此字段僅僅能被搜索,不能獲取到具體的值。6.0.0版本後已廢止。

_field_names:索引了每一個字段的名字,能夠包含 null值,能夠經過 exists查詢或 missing查詢方法來校驗特定的字段

 

文檔元數據

_source : 一個 doc的原生的 json 數據,不會被索引,用於獲取提取字段值,啓動此字段,索引體積會變大,若是既想使用此字段又想兼顧索引體積,能夠開啓索引壓縮。

_source是能夠被禁用的,不過禁用以後部分功能再也不支持,這些功能包括:部分 update api、運行時高亮搜索結果

索引重建、修改 mapping以及分詞、索引升級

debug查詢或者聚合語句

索引自動修復

_size:整個_source 字段的字節數大小,須要單獨安裝一個 mapper-size插件才能展現。

 

路由元數據

_routing:一個 doc能夠被路由到指定的 shard上。

_meta:通常用來存儲應用相關的元信息。

 

其餘

例如:

put /open-soft/_mapping

{

"_meta": {

"class": "cn.enjoyedu.User",

"version": {"min": "1.0", "max": "1.3"}

}

}

管理 Elasticsearch 索引和文檔

  在 es 中,索引和文檔是 REST 接口操做的最基本資源,因此對索引和文檔的管理也是咱們必需要知道的。索引通常是以索引名稱出如今 REST請求操做的資源路徑上,而文檔是以文檔 ID 爲標識出如今資源路徑上。映射類型_doc 也能夠認爲是一種資源,但在 es7 中廢除了映射類型,因此能夠_doc 也視爲一種接口。

 

索引的管理

在前面的學習中咱們已經知道,GET 用來獲取資源,PUT 用來更新資源,DELETE用來刪除資源。因此對索引,GET用來查看索引,PUT用來建立索引,DELETE用來刪除索引,還有一個 HEAD 請求,用來檢驗索引是否存在。除此以外,對索引的管理還有

 

列出全部索引

GET /_cat/indices?v

 

關閉索引和打開

POST /open-soft/_close、、

 

除了刪除索引,還能夠選擇關閉它們。若是關閉了一個索引,就沒法經過Elasticsearch來讀取和寫人其中的數據,直到再次打開它。

在現實世界中,最好永久地保存應用日誌,以防要查看好久以前的信息。另外一方面,在 Elasticsearch 中存放大量數據須要增長資源。對於這種使用案例,關閉舊的索引很是有意義。你可能並不須要那些數據,可是也不想刪除它們。

一旦索引被關閉,它在 Elasticsearch 內存中惟-的痕跡是其元數據,如名字

以及分片的位置。若是有足夠的磁盤空間,並且也不肯定是否須要在那個數據中再次搜索,關閉索引要比刪除索引更好。關閉它們會讓你很是安心,永遠能夠從新打開被關閉的索引,而後在其中再次搜索。

從新打開 POST /open-soft/_open

配置索引

經過 settings參數配置索引,索引的全部配置項都以「index」開頭。索引的管理分爲靜態設置和動態設置兩種。

 

靜態設置

只能在索引建立時或在狀態爲 closed index(閉合索引)上設置,主要配置索引主分片、壓縮編碼、路由等相關信息

index.number_of_shards主分片數,默認爲 5.只能在建立索引時設置,不能修改

index.shard.check_on_startup 是否應在索引打開前檢查分片是否損壞,當檢查到分片損壞將禁止分片被打開。false:默認值;checksum:檢查物理損壞;true:檢查物理和邏輯損壞,這將消耗大量內存和 CPU;fix:檢查物理和邏輯損壞。

有損壞的分片將被集羣自動刪除,這可能致使數據丟失

index.routing_partition_size 自定義路由值能夠轉發的目的分片數。默認爲 1,只能在索引建立時設置。此值必須小於 index.number_of_shards

index.codec 默認使用 LZ4壓縮方式存儲數據,也能夠設置爲

best_compression,它使用 DEFLATE 方式以犧牲字段存儲性能爲代價來得到更高的壓縮比例。

如:

put test1{

"settings":{

"index.number_of_shards":3,

"index.codec":"best_compression"

}

}

 

動態設置

經過接口「_settings」進行,同時查詢配置也經過這個接口進行,好比:get _settings

get /open-soft/_settings

get /open-soft,test1/_settings

配置索引則經過:

put test1/_settings

{

"refresh_interval":"2s"

}

經常使用的配置參數以下:

index.number_of_replicas 每一個主分片的副本數。默認爲 1

index.auto_expand_replicas 基於可用節點的數量自動分配副本數量,默認爲false(即禁用此功能)

index.refresh_interval 執行刷新操做的頻率。默認爲 1s。能夠設置爲 -1 以禁用刷新。

index.max_result_window 用於索引搜索的 from+size 的最大值。默認爲10000

index.blocks.read_only 設置爲 true 使索引和索引元數據爲只讀,false 爲容許寫入和元數據更改。

index.blocks.read 設置爲 true 可禁用對索引的讀取操做

index.blocks.write 設置爲 true 可禁用對索引的寫入操做

index.blocks.metadata 設置爲 true 可禁用索引元數據的讀取和寫入

index.max_refresh_listeners 索引的每一個分片上可用的最大刷新偵聽器數index.max_docvalue_fields_search 一次查詢最多包含開啓 doc_values 字段

的個數,默認爲 100

index.max_script_fields 查詢中容許的最大 script_fields數量。默認爲 32。

index.max_terms_count 能夠在 terms 查詢中使用的術語的最大數量。默認爲65536。

index.routing.allocation.enable 控制索引分片分配。All(全部分片)、primaries(主分片)、new_primaries(新建立分片)、none(不分片)

index.routing.rebalance.enable 索引的分片從新平衡機制。all、primaries、replicas、none

index.gc_deletes 文檔刪除後(刪除後版本號)還能夠存活的週期,默認

爲 60s

index.max_regex_length用於正在表達式查詢(regex query)正在表達式長度,默認爲 1000

 

配置映射

經過_mapping 接口進行,在咱們前面的章節中,已經展現過了。

get /open-soft/_mapping

或者只看某個字段的屬性:

get /open-soft/_mapping/field/lang

修改映射,固然就是經過 put或者 post方法了。可是要注意,已經存在的映射只能添加字段或者字段的多類型。可是字段建立後就不能刪除,大多數參數也不能修改,能夠改的是 ignore_above。因此設計索引時要作好規劃,至少初始時的必要字段要規劃好。

 

增長文檔

增長文檔,咱們在前面的章節已經知道了,好比:

put /open-soft/_doc/1

 {

"name": "Apache Hadoop",

"lang": "Java",

"corp": "Apache",

"stars":200

}

若是增長文檔時,在 Elasticsearch中若是有相同 ID的文檔存在,則更新此文檔,好比執行

put /open-soft/_doc/1

{

"name": "Apache Hadoop2",

"lang": "Java8",

"corp": "Apache",

"stars":300

}

則會發現已有文檔的內容被更新了

 

文檔的 id

當建立文檔的時候,若是不指定 ID,系統會自動建立 ID。自動生成的 ID 是一個不會重複的隨機數。使用 GUID 算法,能夠保證在分佈式環境下,不一樣節點同一時間建立的_id必定是不衝突的。好比:

post /open-soft/_doc

{

"message":"Hello"

}

 

查詢文檔

get /open-soft/_doc/

 

更新文檔

前面咱們用 put方法更新了已經存在的文檔,可是能夠看見他是總體更新文檔,若是咱們要更新文檔中的某個字段怎麼辦?須要使用_update接口。

post /open-soft/_update/1/

{

"doc":{

"year": 2016

}

}

若是文檔中存在 year字段,更新 year 字段的值,若是不存在 year 字段,則會新增 year字段,並將值設爲 2016。

update 接口在文檔不存在時提示錯誤,若是但願在文檔不存在時建立文檔,則能夠在請求中添加 upsert參數或 doc_as_upsert 參數,例如:

POST /open-soft/_update/5

{

"doc": {

"year": "2020"

},

"upsert":{

"name" : "Enjoyedu Framework",

"corp" : "enjoyedu "

}

}

 

POST /open-soft/_update/6

{

"doc": {

"year": "2020"

},

"doc_as_upsert" : true

}

upsert參數定義了建立新文檔使用的文檔內容,而 doc_as_upsert 參數的含義是直接使用 doc參數中的內容做爲建立文檔時使用的文檔內容。

 

刪除文檔

delete /open-soft/_doc/1

 

數據檢索和分析

爲了方便咱們學習,咱們導入 kibana 爲咱們提供的範例數據。

目前爲止,咱們已經探索瞭如何將數據放入 Elasticsearch,如今來討論下如何將數據從 Elasticsearch中拿出來,那就是經過搜索。畢竟,若是不能搜索數據,那麼將其放入搜索引擎的意義又何在呢?幸運的是,Elasticsearch 提供了豐富的接口來搜索數據,涵蓋了 Lucene 全部的搜索功能。由於 Elasticsearch容許構建搜索請求的格式很靈活,請求的構建有無限的可能性。要了解哪些查詢和過濾器的組合適用於你的數據,最佳的方式就是進行實驗,所以不要懼怕在項目的數據上嘗試這些組合,這樣才能弄清哪些更適合你的需求。

 

_search 接口

全部的 REST搜索請求使用_search 接口,既能夠是 GET請求,也能夠是 POST請求,也能夠經過在搜索 URL 中指定索引來限制範圍。

_search 接口有兩種請求方法,一種是基於 URI 的請求方式,另外一種是基於請求體的方式,不管哪一種,他們執行的語法都是基於 DSL(ES 爲咱們定義的查詢語言,基於 JSON的查詢語言),只是形式上不一樣。咱們會基於請求體的方式來學習。好比說:

get kibana_sample_data_flights/_search

{

"query":{

"match_all":{}

}

}

get kibana_sample_data_flights/_search

{

"query":{

"match_none":{}

}

}

固然上面的查詢沒什麼太多的用處,由於他們分別表明匹配全部和全不匹配。

因此咱們常常要使用各類語法來進行查詢,一旦選擇了要搜索的索引,就須要配置搜索請求中最爲重要的模塊。這些模塊涉及文檔返回的數量,選擇最佳的文檔返回,以及配置不但願哪些文檔出如今結果中等等。

■ query-這是搜索請求中最重要的組成部分,它配置了基於評分返回的最佳文檔,也包括了你不但願返回哪些文檔。

■ size-表明了返回文檔的數量。

■ from-和 size 一塊兒使用,from 用於分頁操做。須要注意的是,爲了肯定第2頁的 10 項結果,Elasticsearch 必需要計算前 20 個結果。若是結果集合不斷增長,獲取某些靠後的翻頁將會成爲代價高昂的操做。

■ _source指定_ source 字段如何返回。默認是返回完整的_ source字段。

經過配置_ source,將過濾返回的字段。若是索引的文檔很大,並且無須結果中的所有內容,就使用這個功能。請注意,若是想使用它,就不能在索引映射中關閉_source 字段。

■ sort默認的排序是基於文檔的得分。若是並不關心得分,或者指望許多文檔的得分相同,添加額外的 sort將幫助你控制哪些文檔被返回。

結果起始和頁面大小

命名適宜的 from和 size字段,用於指定結果的開始點,以及每「頁"結果的數量。舉個例子,若是發送的 from 值是 7,size值是 5,那麼 Elasticsearch 將返回第八、九、十、11 和 12項結果(因爲 from 參數是從 0開始,指定 7 就是從第 8項結果開始)。若是沒有發送這兩個參數,Elasticsearch 默認從第一項結果開始(第 0 項結果),在回覆中返回 10項結果。

例如

get kibana_sample_data_flights/_search

{

"from":100,

"size":20,

"query":{

"term":{

"DestCountry":"CN"

}

}

}

可是注意,from與 size 的和不能超過 index. max_result_window 這個索引配置項設置的值。默認狀況下這個配置項的值爲 10000,因此若是要查詢 10000 條之後的文檔,就必需要增長這個配置值。例如,要檢索第 10000 條開始的 200條數據,這個參數的值必需要大於 10200,不然將會拋出相似「Result window is toolarge'的異常。

因而可知,Elasticsearch 在使用 from 和 size處理分頁問題時會將全部數據所有取出來,而後再截取用戶指定範圍的數據返回。因此在查詢很是靠後的數據時,即便使用了 from和 size定義的分頁機制依然有內存溢出的可能,而 max_result_ window設置的 10000條則是對 Elastiesearch 的一.種保護機制。

那麼 Elasticsearch 爲何要這麼設計呢?首先,在互聯網時代的數據檢索應該經過類似度算法,提升檢索結果與用戶指望的附和度,而不該該讓用戶在檢索結果中本身挑選滿意的數據。以互聯網搜索爲例,用戶在瀏覽搜索結果時不多會看到第 3頁之後的內容。假如用戶在翻到第 10000 條數據時尚未找到須要的結果,那麼他對這個搜索引擎必定會很是失望。

 

_source 參數

 

元字段_source 中存儲了文檔的原始數據。若是請求中沒有指定_source,Elasticsearch 默認返回整個_ source,或者若是_ source沒有存儲,那麼就只返回匹配文檔的元數據:_ id、_type、_index 和_score。

例如:

get kibana_sample_data_flights/_search

{

"query":{

"match_all":{}

},

"_source":["OriginCountry","DestCountry"]

}

你不只能夠返回字段列表,還能夠指定通配符。例如,若是想同時返回"

DestCountry "和" DestWeather "字段,能夠這樣配置_ source: "Dest*"。也能夠使用通配字符串的數組來指定多個通配符,例如_ source:[" Origin*", "* Weather "]。

get kibana_sample_data_flights/_search

{

"query":{

"match_all":{}

},

"_source":["Origin*","*Weather"]

}

不只能夠指定哪些字段須要返回,還能夠指定哪些字段無須返回。好比:get kibana_sample_data_flights/_search

{

"_source":{

"includes":["*.lon","*.lat"],

"excludes":"DestLocation.*"

}

}

 

排序

大多搜索最後涉及的元素都是結果的排序( sort )。若是沒有指定 sort 排序選項,Elasticsearch返回匹配的文檔的時候,按照_ score 取值的降序來排列,這樣最爲相關的(得分最高的)文檔就會排名在前。爲了對字段進行升序或降序排列,

 

指定映射的數組,而不是字段的數組。經過在 sort 中指定字段列表或者是字段映射,能夠在任意數量的字段上進行排序。

 

例如:

 

get kibana_sample_data_flights/_search

 

{

 

"from":100,

 

"size":20,

 

"query":{

 

"match_all":{}

 

},

 

"_source":["Origin*","*Weather"],

 

"sort":[{"DistanceKilometers":"asc"},{"FlightNum":"desc"}]

 

}

相關文章
相關標籤/搜索