對於提供全文檢索的工具來說,索引時一個關鍵的過程——只有通過索引操作,才能對數據進行分析存儲、創建倒排索引,從而讓使用者查詢到相關的信息。
本篇就ES的數據索引操作相關的內容展開:
更多內容參考:Elasticsearch資料匯總
索引操作
最簡單的用法就是指定索引操作的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還是理解的不夠透徹,就先不做過多的講述了,免得錯誤太多。
如有異議,還請多多指正。