Elasticsearch入門,這一篇就夠了


實時搜索引擎Elasticsearch

ES為開發者提供了非常豐富的基於HTTP協議的Rest API,只需要向ES服務端發送簡單的Rest請求,就可以實現非常強大的功能。本篇文章主要介紹ES中常用操作的Rest API的使用,同時會講解ES的源代碼工程中的API接口文檔,通過了解這個API文檔的接口描述結構,就基本上可以實現ES中的絕大部分功能。

注意:查詢是ES的核心。作為一個先進的搜索引擎,ES中提供了多種查詢接口。本篇僅僅會涉及查詢API的結構,而具體如何使用ES所提供的各種查詢API,會在接下來的博文中做詳細介紹。

基礎知識

如果之前沒有用過類似於ES這樣的索引數據庫(暫且將ES歸為數據庫類,與傳統的數據庫有較大的區別),要理解本篇博文介紹的API是有些難度的。本節先介紹一些基礎知識,對理解全文有很幫助。

Rest介紹

筆者在學習軟件開發過程中,多次聽到過Rest Http這個概念,但在很長的一段時間里,死活搞不懂這玩意到底是個什么東西。剛開始看相關資料時,看得雲里霧里,完全不知所雲 _。這玩意太過於抽象和理論,心里覺得有必要搞這么復雜么。隨着自己動手開發的東西越來越多,才開始對它有了一丟丟感覺。

Rest完全不是三言兩語就能將清楚的,它有自己的一套體系,所以筆者打算以后單獨寫一些有關Rest的博文。在這里推薦一篇優秀的文章,它對Rest講的相當清楚,本人看完之后真有醍醐灌頂的感覺!

Mapping詳解

Mapping是ES中的一個很重要的內容,它類似於傳統關系型數據中table的schema,用於定義一個索引(index)的某個類型(type)的數據的結構。

在傳統關系型數據庫,我們必須首先創建table並同時定義其schema,如下面的SQL語句。下面代碼中小括號內的代碼的作用就是定義person_info的schema(模式)。

create table person_info ( name varchar(20), age tinyint )

 

在ES中,我們無需手動創建type(相當於table)和mapping(相關與schema)。在默認配置下,ES可以根據插入的數據自動地創建type及其mapping。在下面的API介紹部分中,會做相關的試驗。當然,在實際使用過程中我們可能就想硬性規定mapping,可以通過配置文件關閉ES的自動創建mapping功能。

mapping中主要包括字段名、字段數據類型和字段索引類型這3個方面的定義。

字段名:這就不用說了,與傳統數據庫字段名作用一樣,就是給字段起個唯一的名字,好讓系統和用戶能識別。

字段數據類型:定義該字段保存的數據的類型,不符合數據類型定義的數據不能保存到ES中。下表列出的是ES中所支持的數據類型。(大類是對所有類型的一種歸類,小類是實際使用的類型。)

大類 包含的小類
String string
Whole number byte, short, integer, long
Floating point float, double
Boolean boolean
Date date

字段索引類型:索引是ES中的核心,ES之所以能夠實現實時搜索,完全歸功於Lucene這個優秀的Java開源索引。在傳統數據庫中,如果字段上建立索引,我們仍然能夠以它作為查詢條件進行查詢,只不過查詢速度慢點。而在ES中,字段如果不建立索引,則就不能以這個字段作為查詢條件來搜索。也就是說,不建立索引的字段僅僅能起到數據載體的作用。string類型的數據肯定是日常使用得最多的數據類型,下面介紹mapping中string類型字段可以配置的索引類型。

索引類型 解釋
analyzed 首先分析這個字符串,然后再建立索引。換言之,以全文形式索引此字段。
not_analyzed 索引這個字段,使之可以被搜索,但是索引內容和指定值一樣。不分析此字段。
no 不索引這個字段。這個字段不能被搜索到。

如果索引類型設置為analyzed,在表示ES會先對這個字段進行分析(一般來說,就是自然語言中的分詞),ES內置了不少分析器(analyser),如果覺得它們對中文的支持不好,也可以使用第三方分析器。由於筆者在實際項目中僅僅將ES用作普通的數據查詢引擎,所以並沒有研究過這些分析器。如果將ES當做真正的搜索引擎,那么挑選正確的分析器是至關重要的。

mapping中除了上面介紹的3個主要的內容外,還有其他的定義內容,詳見官網文檔

常用的Rest API介紹

下面介紹一下ES中的一些常用的Rest API。掌握了這些API的用法,基本上就可以簡單地使用ES了。

我們需要借助能夠發送HTTP請求的工具調用這些API,工具是可以任意的,包括網頁瀏覽器。這里利用Linux上的curl命令來發送HTTP請求。基本的命令結構為:

  curl <-Xaction> url -d 'body' # 這里的action表示HTTP協議中的各種動作,包括GET、POST、PUT、DELETE等。

 

注意。文中的示例代碼里面包含了用戶注釋的文字,就是 # 號后面的文字。運行代碼時,請注意刪除這些注釋。

查看集群(Cluster)信息相關API

(1)查看集群健康信息。

  curl -XGET "localhost:9200/_cat/heath?v"

返回結果為:

epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks 1440206633 18:23:53 elasticsearch green 1 1 0 0 0 0 0 0 

 

返回結果的主要字段意義:

  • cluster:集群名,是在ES的配置文件中配置的cluster.name的值。
  • status:集群狀態。集群共有green、yellow或red中的三種狀態。green代表一切正常(集群功能齊全),yellow意味着所有的數據都是可用的,但是某些復制沒有被分配(集群功能齊全),red則代表因為某些原因,某些數據不可用。如果是red狀態,則要引起高度注意,數據很有可能已經丟失。
  • node.total:集群中的節點數。
  • node.data:集群中的數據節點數。
  • shards:集群中總的分片數量。
  • pri:主分片數量,英文全稱為private。
  • relo:復制分片總數。
  • unassign:未指定的分片數量,是應有分片數和現有的分片數的差值(包括主分片和復制分片)。

我們也可以在請求中添加help參數來查看每個操作返回結果字段的意義。

  curl -XGET "localhost:9200/_cat/heath?help"

返回結果如下:

epoch         | t,time | seconds since 1970-01-01 00:00:00 timestamp | ts,hms,hhmmss | time in HH:MM:SS cluster | cl | cluster name status | st | health status node.total | nt,nodeTotal | total number of nodes node.data | nd,nodeData | number of nodes that can store data shards | t,sh,shards.total,shardsTotal | total number of shards pri | p,shards.primary,shardsPrimary | number of primary shards relo | r,shards.relocating,shardsRelocating | number of relocating nodes init | i,shards.initializing,shardsInitializing | number of initializing nodes unassign | u,shards.unassigned,shardsUnassigned | number of unassigned shards pending_tasks | pt,pendingTasks | number of pending tasks 

 

確實是很好很強大。有了這個東東,就可以減少看文檔的時間。ES中許多API都可以添加help參數來顯示字段含義,哪些可以這么做呢?每個API都試試就知道了。

當然,如果你覺得返回的東西太多,看着眼煩,我們也可以人為地指定返回的字段。

  curl -XGET "localhost:9200/_cat/health?h=cluster,pri,relo&v"

這次的返回結果就簡單很多羅。對於患有嚴重強迫症的患者來說,這是福音啊!

cluster pri relo elasticsearch 0 0 

(2)查看集群中的節點信息。

  curl -XGET "localhost:9200/_cat/nodes?v"

返回節點的詳細信息如下:

host          ip            heap.percent ram.percent load node.role master name master.hadoop localhost 3 35 0.00 d * Ezekiel 

 

(3)查看集群中的索引信息。

  curl -XGET "localhost:9200/_cat/indices?v"

 

返回集群中的索引信息如下:

health status index      pri rep docs.count docs.deleted store.size pri.store.size yellow open index_test 5 1 0 0 575b 575b 

 

更多的查看和監視ES的API參見官網文檔

索引(Index)相關API

(1)創建一個新的索引。

curl -XPUT "localhost:9200/index_test"

如果返回下面的信息,則說明索引創建成功。如果不是,則ES會返回相應的異常信息。通常可以通過異常信息的最后一項推斷出失敗的原因。

{
    "acknowledged": true }

上面的操作使用默認的配置信息創建一個索引。大多數情況下,我們想在索引創建的時候就將我們所需的mapping和其他配置確定好。下面的操作就可以在創建索引的同時,創建settings和mapping。

curl -XPUT "localhost:9200/index_test" -d ' # 注意這里的'號 { "settings": { "index": { "number_of_replicas": "1", # 設置復制數 "number_of_shards": "5" # 設置主分片數 } }, "mappings": { # 創建mapping "test_type": { # 在index中創建一個新的type(相當於table) "properties": { "name": { # 創建一個字段(string類型數據,使用普通索引) "type": "string", "index": "not_analyzed" }, "age": { "type": "integer" } } } } }'

 

(2)刪除一個索引。

curl -XDELETE "localhost:9200/index_test"

如果返回與創建索引同樣的信息,則說明刪除成功。反之,則返回相應的異常信息。更多的索引操作參見ES官網文檔

映射(Mapping)相關API

(1)創建索引的mapping。

curl -XPUT 'localhost:9200/index_test/_mapping/test_type' -d ' { "test_type": { # 注意,這里的test_type與url上的test_type名保存一致 "properties": { "name": { "type": "string", "index": "not_analyzed" }, "age": { "type": "integer" } } } }'

 

如果不想單獨創建mapping,可以使用上一節的方法(創建索引時創建mappings)。

假設我們的項目中有多個環境(開發環境、測試環境等),那每一個環境的mapping總要一致的吧,那每次創建一次mappings就比較麻煩了,而且還容易導致數據不一致。莫急,ES還給我們准備另外一種創建mapping的方式。可以按照下面的步驟來做。

步驟1 創建一個擴展名為test_type.json的文件名,其中type_test就是mapping所對應的type名。

步驟2 在test_type.json中輸入mapping信息。假設你的mapping如下:

{
  "test_type": { # 注意,這里的test_type與json文件名必須一致 "properties": { "name": { "type": "string", "index": "not_analyzed" }, "age": { "type": "integer" } } } }

 

步驟3 在$ES_HOME/config/路徑下創建mappings/index_test子目錄,這里的index_test目錄名必須與我們要建立的索引名一致。將test_type.json文件拷貝到index_tes目錄下。

步驟4 創建index_test索引。操作如下:

curl -XPUT "localhost:9200/index_test" # 注意,這里的索引名必須與mappings下新建的index_test目錄名一致

這樣我們就創建了一個新的索引,並且使用了test_type.json所定義的mapping作為索引的mapping。就是這么簡單方便!

(2)刪除mapping。

curl -XDELETE 'localhost:9200/index_test/_mapping/test_type'

(3)查看索引的mapping。

curl -XGET 'localhost:9200/index_test/_mapping/test_type'

 

更多的mapping相關操作參加官網文檔

文檔(document)相關API

(1)新增一個文檔。

curl -XPUT 'localhost:9200/index_test/test_type/1?pretty' -d ' # 這里的pretty參數的作用是使得返回的json顯示地更加好看。1是文檔的id值(唯一鍵)。 { "name": "zhangsan", "age" : "12" }'

 

(2)更新一個文檔

curl -XPOST 'localhost:9200/index_test/test_type/1?pretty' -d ' # 這里的1必須是索引中已經存在id,否則就會變成新增文檔操作 { "name": "lisi", "age" : "12" }' 

 

(3)刪除一個文檔

curl -XDELETE 'localhost:9200/index_test/test_type/1?pretty' # 這里的1必須是索引中已經存在id

 

(4)查詢單個文檔

curl -XGET 'localhost:9200/index_test/test_type/1?pretty'

 

上面的操作僅僅查詢id為1的一條文檔,這樣看似乎ES的查詢也太弱了。前面已經說過了,查詢操作是ES中的核心,是其立身的根本。但是本文的重點並不在這里,為了防止文章的篇幅過長,之后將專本介紹ES中的查詢操作。

源代碼中提供的Rest API文檔結構

ES的源代碼托管在Github上。將源代碼下載下來之后,里面有一個文件夾專門存放ES中絕大部分的Rest API。有了這些文檔,就不必每次都要到官網上查詢接口文檔了(PS:ES的官網真的很慢)。 
下面以cat.health.json文件為例簡單地介紹這些Rest API文檔的結構。一旦結構搞清楚了,文檔看起來就比較順心,ES用起來就更加得心應手了!

{
  "cat.health": { "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/master/cat-health.html", # 該文檔對應的官方站點 "methods": ["GET"], "url": { # url部分可選 "path": "/_cat/health", "paths": ["/_cat/health"], "parts": { }, "params": { "local": { "type" : "boolean", "description" : "Return local information, do not retrieve the state from master node (default: false)" }, "master_timeout": { "type" : "time", "description" : "Explicit operation timeout for connection to master node" }, "h": { "type": "list", "description" : "Comma-separated list of column names to display" }, "help": { "type": "boolean", "description": "Return help information", "default": false }, "ts": { "type": "boolean", "description": "Set to false to disable timestamping", "default": true }, "v": { "type": "boolean", "description": "Verbose mode. Display column headers", "default": true } } }, "body": null } }

 

 

上面文檔接口所對應的Reqeust操作如下:

curl -XGET "localhost:9200/_cat/health?v" -d 'body'

 

該操作命令可划分為5個部分,下面把這5個部分與文檔對應起來。通過這個例子,就可以在閱讀其他文檔后,使用正確的操作了。

  1. 第1部分(-XGET):對應文檔中methods所包含的GET操作。
  2. 第2部分(localhost:9200):是ES服務端所在主機的hostname和port。
  3. 第3部分(/_cat/health):對應文檔中的url。其中path是最簡單的url;paths是除了path之外的其他url;parts描述和解釋paths里面的url的可變部分(通常用{}包裹,如{index})。
  4. 第4部分v:表示參數,對應文檔中的params。像“v”這種boolean類型的參數,不需要特意指定其布爾值(true或者false),出現即表示true,否則為false。
  5. 第5部分body:表示要傳遞的數據主體,對應文檔中的body。如果body里面指明“required=true”,則表示必須傳入body數據。具體body里面需要傳怎樣的數據,則可以訪問文檔中的documentation字段所指明的官方站點進行查詢。

總結

本文重點介紹了ES中的一些常用Rest API的用法,並在開始部分簡單地介紹了一些基礎知識(Rest和mapping)。掌握了這些API的調用,就可以利用ES完成簡單的應用程序了。當然,ES的API遠不止這些,如果想要更加深入地了解ES的使用及其內部原理,建議先仔細地閱讀ES的官網文檔。然后下載其源代碼進行研究。

 

想進階的同學,請參考:

Elasticsearch: 權威指南

 

 


免責聲明!

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



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