Elasticsearch 之 資料索引
對於提供全文檢索的工具來說,索引時一個關鍵的過程——只有通過索引操作,才能對資料進行分析儲存、建立倒排索引,從而讓使用者查詢到相關的資訊。
本篇就ES的資料索引操作相關的內容展開:
索引操作
最簡單的用法就是指定索引操作的index索引、type型別、ID(需要區分動詞的索引和名次的索引),參考下面的例子:
$ curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{ "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }'
這樣就在索引twitter中的tweet型別中儲存了id為1的資料。
索引操作的結果為:
{ "_shards" : { "total" : 10, "failed" : 0, "successful" : 10 }, "_index" : "twitter", "_type" : "tweet", "_id" : "1", "_version" : 1, "created" : true }
上面的_shards中描述了分片相關的資訊,即當前一共有10個分片(5個主分片,5個副分片,並且均可用);以及index、type、id、version相關的資訊。
自動建立索引
如果上面執行操作前,ES中沒有twitter這個索引,那麼預設會直接建立這個索引;並且type欄位也會自動建立。也就是說,ES並不需要像傳統的資料庫事先定義表的結構。
每個索引中的型別都有一個mapping對映,這個對映是動態生成的,因此當增加新的欄位時,會自動增加mapping的設定。
通過在配置檔案中設定action.auto_create_index為false,可以關閉自動建立index這個功能。
自動建立索引功能,也可以設定黑名單或者白名單,比如:
設定action.auto_create_index為 +aaa*,-bbb*,'+'號意味著允許建立aaa開頭的索引,'-'號意味著不允許建立bbb開頭的索引
關於版本號
版本號維護了一個文件的狀態,我們只會針對最高版本號的文件進行操作。
文件號不僅可以在文件中進行儲存,也可以在外部維護版本號,具體的參考官方文件吧....
操作型別op_type
ES通過引數op_type提供“缺少即加入”的功能,即如果ES中沒有該文件,就進行索引;如果有了,則報錯返回。
如果已經存在id為1的文件,則會報錯,直接使用_create API,效果一樣:
自動建立ID:
按照最上面的例子來說,ES會把我們指定的文件id做為ID。如果不指定ID,那麼就會隨機分配一個:
路由routing
ES是通過路由來進行查詢的,一般一個查詢會經過下面的過程:
1 節點接收請求,廣播給每個分片
2 分片接收請求,進行計算,返回結果
3 合併訊息,返回
如果我們設定了路由資訊,就相當於告訴了ES,該去哪個分片查詢資料,也就取消了廣播合併這個過程,從而提高了查詢的效率。使用方法:
$ curl -XPOST 'http://localhost:9200/twitter/tweet?routing=kimchy' -d '{ "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }'
路由是通過雜湊來實現的,如果我們在索引的時候直接指定routing的值,就會按照這個值計算雜湊值,分配分片;如果不指定,就會根據ID來分配。由於一般情況下ID都是隨機生成的,這樣就可以保證預設情況下分片的資料負載是相同的。如果我們需要在特定的分片儲存特定的內容,就可以使用路由指定分片。不過這樣做,日後隨著資料量的增加,也可能會導致某個分片壓力過大。
另外,也可以在定義mapping的時候,直接設定routing的相關值。這樣這個型別中的資料如果不指定routing的值,預設就會使用mapping中定義的那個路由值。
parent設定父子關係
ES中可能會涉及到一些文件的從屬關係,使用parent引數,可以設定這種關係:
$ curl -XPUT localhost:9200/blogs/blog_tag/1122?parent=1111 -d '{ "tag" : "something" }'
_timestamp設定時間戳
時間戳欄位可以也可以在索引操作時指定:
$ curl -XPUT localhost:9200/twitter/tweet/1?timestamp=2009-11-15T14%3A12%3A12 -d '{ "user" : "kimchy", "message" : "trying out Elasticsearch" }'
如果沒有手動指定時間戳,_source中也不存在時間戳,就會設定為索引指定的時間。不過需要指定mapping中的_timestamp設定為enable
PUT my_index { "mappings": { "my_type": { "_timestamp": { "enabled": true } } } }
ttl文件過期
ES中也可以設定文件自動過期,過期是設定一個正的時間間隔,然後以_timestamp為基準,如果超時,就會自動刪除。
如果設定為時間戳:
curl -XPUT 'http://localhost:9200/twitter/tweet/1?ttl=86400000' -d '{ "user": "kimchy", "message": "Trying out elasticsearch, so far so good?" }'
如果設定為日期數學表示式:
curl -XPUT 'http://localhost:9200/twitter/tweet/1?ttl=1d' -d '{ "user": "kimchy", "message": "Trying out elasticsearch, so far so good?" }'
也可以在JSON欄位中指定:
curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{ "_ttl": "1d", "user": "kimchy", "message": "Trying out elasticsearch, so far so good?" }'
手動重新整理
由於ES並不是一個實時索引搜尋的框架,因此資料在索引操作後,需要等1秒鐘才能搜尋到。這裡的搜尋是指進行檢索操作。如果你使用的是get這種API,就是真正的實時操作了。他們之間的不同是,檢索可能還需要進行分析和計算分值相關性排序等操作。
為了在資料索引操作後,馬上就能搜尋到,也可以手動執行refresh操作。只要在API後面新增refresh=true即可。
這種操作僅推薦在特殊情況下使用,如果在大量所以操作中,每個操作都執行refresh,那是很耗費效能的。
Timeout超時
分片並不是隨時可用的,當分片進行備份等操作時,是不能進行索引操作的。因此需要等待分片可用後,再進行操作。這時,就會出現一定的等待時間,如果超過等地時間則返回並丟擲錯誤,這個等待時間可以通過timeout設定:
$ curl -XPUT 'http://localhost:9200/twitter/tweet/1?timeout=5m' -d '{ "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }'
以上便是索引操作相關的知識,還有一些高階的知識,比如分片和版本號詳細的用法,由於對ES還是理解的不夠透徹,就先不做過多的講述了,免得錯誤太多。
如有異議,還請多多指正。