1. 程式人生 > >Elasticsearch增刪改查 之 —— Get查詢

Elasticsearch增刪改查 之 —— Get查詢

GET API是Elasticsearch中常用的操作,一般用於驗證文件是否存在;或者執行CURD中的文件查詢。與檢索不同的是,GET查詢是實時查詢,可以實時查詢到索引結果。而檢索則是需要經過處理,一般預設是1秒鐘吧...才能搜尋到。合理利用這些方法,可以更靈活的使用Elasticsearch。
更多內容參考ELK教程

閱讀這篇文件,發現自己對很多地方不是很理解。比如儲存機制、版本維護等等。暫時先做為階段性的學習吧...後續更新在回來補補....

查詢樣例

Get API允許基於ID欄位從Elasticsearch查詢JSON文件,下面就是一個查詢的例子:

curl -XGET 'http://localhost:9200/twitter/tweet/1'

上面的命令表示,在twitter索引的tweet型別中查詢id為1的文件,返回結果如下:

{
    "_index" : "twitter",
    "_type" : "tweet",
    "_id" : "1",
    "_version" : 1,
    "found": true,
    "_source" : {
        "user" : "kimchy",
        "postDate" : "2009-11-15T14:12:12",
        "message" : "trying out Elasticsearch"
    }
}

上面返回的資料包括文件的基本內容,_index

是索引名稱,_type是型別,_id是ID,_version是版本號。_source欄位包括了文件的基本內容;found欄位代表是否找到。

這個API支援使用HEAD方式提交,這樣可以驗證這個ID是否存在,而不會返回無用的資料。

curl -XHEAD -i 'http://localhost:9200/twitter/tweet/1'

實時

預設情況下get API是實時的,並不會受到索引的重新整理頻率的影響。(也就是說,只要索引的資料,就可以立馬查詢到)

有的時候我們可能想要關閉實時查詢,這樣可以設定realtime=false。也可以在配置檔案中配置,使之全域性可用,即配置action.get.realtime為false。

When getting a document, one can specify fields to fetch from it. They will, when possible, be fetched as stored fields (fields mapped as stored in the mapping). When using realtime GET, there is no notion of stored fields (at least for a period of time, basically, until the next flush), so they will be extracted from the source itself (note, even if source is not enabled). It is a good practice to assume that the fields will be loaded from source when using realtime GET, even if the fields are stored.當查詢文件的時候,可以從文件中獲取特定的欄位。一般來說這些欄位可能是被儲存的。當我們使用實時GET查詢的時候,就會忽略這些儲存的欄位,直接從source裡面拿到欄位資料。---- 個人不是很理解這段,於是把原文貼上來,要是理解錯誤,還請指正。

記得對映型別中,欄位有幾個屬性,型別、是否被儲存、是否被分析,我猜想上面指的應該就是這個被儲存吧。也就是說,GET查詢的時候並不會從這些儲存的欄位中查資料,而是直接從source中查詢。那麼這些儲存的欄位使用來幹嘛的呢?暫且記下....說不定以後整理的文件中會遇到!

型別可選

API中型別_type是可選的,如果想要查詢所有的型別,可以直接指定型別為_all,從而匹配所有的型別。

source過濾

預設情況下get操作會返回_source欄位,除非你使用了fields欄位或者禁用了_source欄位。通過設定_source屬性,可以禁止返回source內容:

curl -XGET 'http://localhost:9200/twitter/tweet/1?_source=false'

如果想要返回特定的欄位,可以使用_source_include或者_source_exclude進行過濾。可以使用逗號分隔來設定多種匹配模式,比如:

curl -XGET 'http://localhost:9200/twitter/tweet/1?_source_include=*.id&_source_exclude=entities'

如果希望返回特定的欄位,也可以直接寫上欄位的名稱:

curl -XGET 'http://localhost:9200/twitter/tweet/1?_source=*.id,retweeted'

欄位

get操作允許設定fields欄位,返回特定的欄位:

curl -XGET 'http://localhost:9200/twitter/tweet/1?fields=title,content'

如果請求的欄位沒有被儲存,那麼他們會從source中分析出來,這個功能也可以用source_filter來替代。

元資料比如_routing_parent是永遠不會被返回的。

Also only leaf fields can be returned via the field option. So object fields can’t be returned and such requests will fail.只有葉子欄位才能通過field選項返回.所以物件欄位這種是不能返回的,這種請求也會失敗。

Generated fields

如果在執行完索引操作,沒有重新整理,那麼GET操作會讀取translog的內容來查詢文件。然而有一些欄位僅僅是在索引的時候產生的。如果你嘗試讀取索引中的生成的欄位,就會出現錯誤。可以設定ignore_erros_on_generated_fields=true來忽略錯誤。

其實個人也不太理解這個生成欄位是什麼意思?

不過這個Translog比較有意思,是在文件的後面才有介紹。就是索引的資料要進行儲存,那麼總不可能索引一條就更新一次Lucene結構吧。所以就搞了個translog,資料的變動會先放在translog裡面,再重新整理到es中。實時查詢,其實是讀取了translog中,還未持久化的資料。

僅返回_source

使用/{index}/{type}/{id}/_source可以僅僅返回_source欄位,而不必返回過多不必要的資訊,浪費網路頻寬。

curl -XGET 'http://localhost:9200/twitter/tweet/1/_source'

也可以使用過濾機制:

curl -XGET 'http://localhost:9200/twitter/tweet/1/_source?_source_include=*.id&_source_exclude=entities'

也是支援使用HEAD方式,驗證是否存在:

curl -XHEAD -i 'http://localhost:9200/twitter/tweet/1/_source'

路由

當索引的時候指定了路由,那麼查詢的時候就一定要指定路由。

curl -XGET 'http://localhost:9200/twitter/tweet/1?routing=kimchy'

如果路由資訊不正確,就會查詢不到文件

Preference

控制為get請求維護一個分片的索引,這個索引可以設定為:

  • _primary 這個操作僅僅會在主分片上執行。
  • _local 這個操作會在本地的分片上執行。
  • Custom (string) value 使用者可以自定義值,對於相同的分片可以設定相同的值。這樣可以保證不同的重新整理狀態下,查詢不同的分片。就像sessionid或者使用者名稱一樣。

重新整理

refresh引數可以讓每次get之前都重新整理分片,使這個值可以被搜尋。設定true的時候,儘量要考慮下效能問題,因為每次重新整理都會給系統帶來一定的壓力

分散式

get操作會通過特定的雜湊方法,把請求分配給特定的分片進行查詢。由於在分散式的環境下,主分片和備份分片作為一個組,都可以支援get請求。這就意味著,分片的數量越多,get執行的規模就越大。

版本

You can use the version parameter to retrieve the document only if it’s current version is equal to the specified one. This behavior is the same for all version types with the exception of version type FORCE which always retrieves the document.你可以使用version引數檢索文件,不過version引數的值必須等於當前版本號。當版本型別為FORCE的時候,所有的版本型別都可以檢索文件。

關於es的版本號,理解的真是不夠透徹....

在ES的內部,會給那些被刪除或者被整個替換的文件打上一個標記。老版本的文件並不會立即刪除,當然你也不能訪問到它。ES會在後臺清理,以便能有更多的空間索引資料。