1. 程式人生 > >Elasticsearch 用 REST API操作資料的CRUD(增刪改查)

Elasticsearch 用 REST API操作資料的CRUD(增刪改查)

restful adj.平靜的,悠閒的,讓人得到休息的;安生。
Elasticsearch REST API可用於各種任務。有了它,可以管理索引,更改例項引數,檢查節點和群集狀態,索引資料,搜尋資料或者通過GET API檢索文件。但是現在,我們將集中在API中的CRUD(create-retrieve-update-delete,增刪改查)部分,它讓我們能像使用NoSQL資料庫一樣使用Elasticsearch。

理解 Elasticsearch 的 RESTful API 
假設現在有如下路徑:/books/1/chapter/6
上述路徑可以理解為:在圖書館的所有書這張表中,ID為1的書,章節為6.
我們在使用 Elasticsearch 的 RESTful API 的時候,也是這麼個效果。就是每個URL都代表具體的東西。反正就是根據路徑去查你想要的東西。查詢你想要的東西的條件都是在路徑中得到體現。
具體詳細理解,可參考如下的對應。
curl -X<VERB> <PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING> -d '<BODY>'
VERB HTTP方法:GET, POST, PUT, HEAD, DELETE
PROTOCOL http或者https協議(只有在Elasticsearch前面有https代理的時候可用)
HOST Elasticsearch叢集中的任何一個節點的主機名,如果是在本地的節點,那麼就叫localhost
PORT Elasticsearch HTTP服務所在的埠,預設為9200
PATH API路徑(例如_count將返回叢集中文件的數量),PATH可以包含多個元件,例如_cluster/stats或者_nodes/stats/jvm
QUERY_STRING 一些可選的查詢請求引數,例如?pretty引數將使請求返回更加美觀易讀的JSON資料
BODY 一個JSON格式的請求主體(如果請求需要的話)
上面的對應下面的例子。get請求可以直接在瀏覽器上輸入,下面的在mac的命令列可以執行。後面的 -d 後面的我就沒有測試了。
當Windows上裝了curl的外掛 也是可以的,但是我測試的時候,後面 -d 的一堆東西是失敗的。後面加的這個body不能用。
(後來測試,是Windows解析json的問題,由雙引號引起,具體處理,此類文章有說明)
curl -XGET http://localhost:9200/_count?pretty -d ‘{
    "query": {
        "match_all": {}
    }
}’


先不要在意為什麼帶引數就失敗了吧。也許學著學著,就知道哪裡錯了呢,也許是書上寫錯了呢。或者版本升級的問題呢。
(經過後面的測試發現,這個是Windows 的cmd 命令列對雙引號的解釋的問題,mac就不會有問題,我有做測試,在下面新建文件的時候,就出這個問題了。)

理解了上面的東西,也就理解了 REST 的一般概念。
你可以在 http://en.wikipedia.org/wiki/Representational_state_transfer 上閱讀更多關於REST的資訊。具體的我還沒點進去看呢。

下面繼續 如何使用Elasticsearch API 來實現 CRUD

在Elasticsearch中,所有的資料,即每個文件,都有定義好的索引和型別。每個文件可以包含一個或多個欄位來儲存資料。首先展示如何使用Elasticsearch為一個簡單文件建立索引。

新建文件(先新建資料,然後才可以索引)

現在,嘗試索引一些文件。例如,為部落格建立某種內容管理系統(CMS)。文章(article)是部落格中的一個實體(model)。
使用JSON物件表示,一個文件可以用如下所示的例子來表示:
{
    "id": "1",
    "title": "New version of Elasticsearch released!",
    "content": "Version 1.0 released today!",
    "priority": 10,
    "tags": ["announce", "elasticsearch","release" ]
}
可以看到,JSON文件包含一組欄位,每個欄位可以有不同的形式。在以上示例中,我們所使用的型別有數字(priority翻譯為優先權,)、文字(title)和字串陣列(tags)。Elasticsearch能猜出這些型別(因為JSON是半型別化的,例如,數字沒有放在引號中),並自動定製這些資料在其內部結構中如何儲存。

當然,我們希望為示例文件建立索引,並使其可用於搜尋。我們將使用一個名為blog的索引和名為article的型別。為了把示例文件以給定型別、識別符號為1建立在索引中,執行以下命令:
curl -XPUT http://localhost:9200/blog/article/1 -d '{"title": "New version of Elasticsearch released!","content": "Version1.0releasedtoday!","tags": [ "announce","elasticsearch","release"]}'
好吧,上面的命令是可以直接在mac命令列執行的,在Windows上,即使裝curl外掛,還是得修改下,加很多的引號,也是可以正確執行的。
具體命令修改為如下,執行的時候,命令裡面不要換行:
curl -XPUT "http://localhost:9200/blog/article/1" -d "{"""title""": """New version of Elasticsearch released!""", """content""": """Version 1.0 released today!""","""tags""":"""["announce", "elasticsearch", "release"]"""}"
正確執行,新建文件的命令的截圖如下:


然後看到這個時候head外掛的頁面就可以看到資料了,主要看2個地方的截圖吧。



看到圖裡面的索引為_index,型別_type,_id文件的識別符號,三個欄位 title content tags。
為了更好的瞭解這幾個東西,我又給es新建了2個文件,和上面的不相干的文件。測試的是我,你看著又不累,還是乖乖繼續看吧。
curl -XPUT "http://127.0.0.1:9200/index/type/id" -d "{ """attribute""" : """name""" }"
curl -XPUT "http://127.0.0.1:9200/index/type/id2" -d "{ """attribute""" : """lxk""" }"
然後,現在的圖如下。



看圖裡面的東西,知道,所有的文件的欄位都被顯示在欄位的下面,可以找到對應欄位,直接搜尋。然後看到索引和型別暫時的作用可以分組用。然後所有的文件資料都是在右邊顯示,看上去像所有資料都在一張表上一樣。_id這個欄位,唯一識別符號。來區分每一個文件。
暫時就得到這麼多資訊吧。

識別符號的自動建立

上面的識別符號(_id 欄位)是我們指定生成的。但是這個也可以自動生成。就像資料庫裡面的ID,一般不指定,都是自動生成,我看mongo就是這麼的。下面測試自動生成這個識別符號欄位。
Elasticsearch可以自動生成識別符號。這似乎很方便,但只有當該索引是唯一的資料來源時,才能這麼做。如果使用一個數據庫來儲存資料,用Elasticsearch全文搜尋,那資料同步將會被阻礙,除非在資料庫中也儲存生成的識別符號。使用HTTP POST請求型別並且不在URL中指定識別符號,就可以生成一個唯一識別符號。
(上面這句話我就沒看明白具體是啥意思。那就暫時先不管這個吧)
看下面的命令:
mac 環境下的命令列,我就不測試了。
curl -XPOST http://localhost:9200/blog/article/ -d '{"title": "New version of Elasticsearch released!", "content": "Version 1.0 released today!", "tags":["announce", "elasticsearch", "release"] }'
Windows cmd 環境下
curl -XPOST "http://localhost:9200/blog/article/" -d "{"""title""": """New version of Elasticsearch released!""", """content""": """Version 1.0 released today!""", """tags""":"""["announce", "elasticsearch", "release"]""" }'
然後,上執行結果的圖:


再看head的外掛上的頁面的結果。發現如下:
我是把原來的2個節點都刪除了,然後再次測試的結果圖。在概覽頁可以看到有一條doc存在,但是在資料瀏覽頁面上卻沒有看到,但是,還好我學過web的,所以,看了url的請求。看到確實是有資料返回的。暫時先這麼理解吧。



後面我就想不開,為什麼就是不顯示呢?然後就仔細對比了下自動生成的識別符號和自己指定識別符號的區別。不是幹Java的嗎,都知道點web的知識。然後我就把2次的_search請求的返回結果json資料,拿到 http://www.bejson.com/ 這個工具頁面給格式化下,發現,返回資料json格式化失敗,再看下發現我的雙引號加的不對。最後一個引號是單引號。
那麼再次修改下,Windows cmd 環境下的命令。
curl -XPOST "http://localhost:9200/blog/article/" -d "{"""title""": """New version of Elasticsearch released!""", """content""": """Version 1.0 released today!""", """tags""":"""["announce", "elasticsearch", "release"]""" }"
再次執行以下就OK了。頁面就OK了。



為什麼不直接寫正確的結果呢,額,這個就是個實際開發中排錯的經驗吧。實際開發中,這個json格式不對的bug估計多了去了。多半都是引數的問題。

最後我又試試,把上面的三個新建文件的都一起執行,看看效果。因為瀏覽長度有限,下面是有滾動條的。圖裡就展現不出來了。


檢索文件

上面既然已經新建資料OK,那麼下面就可以讀資料了。
curl -XGET http://localhost:9200/blog/article/1
這個命令,因為後面沒有 -d 帶引數,所以,可惡的雙引號就可以不考慮了。
執行結果如下,圖上可以看到後面跟上引數 ?pretty,可以使得返回的json結果字串格式化,看著舒服點。


解釋:
除了索引、型別、識別符號和版本,還可以看到說明“發現檔案存在”(exists屬性)以及此文件來源(_source屬性)的資訊。

更新文件

mac 環境下的命令列,我就不測試了。暫時沒mac。
curl -XPOST http://localhost:9200/blog/article/1/_update -d '{ "script": "ctx._source.content = \"new content\"" }'
Windows cmd 環境下 加引號吧。。暫時的處理辦法。
curl -XPOST "http://localhost:9200/blog/article/1/_update" -d "{ """script""": """ctx._source.content = \\\"new content\\\" """ }"

這個Windows下的命令暫時是錯誤的,至於,具體怎麼修復這個bug,再續吧。