Elasticsearch 之 數據索引


對於提供全文檢索的工具來說,索引時一個關鍵的過程——只有通過索引操作,才能對數據進行分析存儲、創建倒排索引,從而讓使用者查詢到相關的信息。

本篇就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還是理解的不夠透徹,就先不做過多的講述了,免得錯誤太多。

如有異議,還請多多指正。


免責聲明!

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



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