2014年7月6日 星期日

Elasticsearch 第一發 - 入門筆記

是說....,你是否有搜尋過,單字的 『Elastic』 是什麼意思嗎 :P


Elasticsearch 是一個開源的資料搜尋分析系統,它可以解決現在 Web 去做資料庫的搜尋的種種問題,嚴格來說也不只是 web,(有可能是為了撈資料的效能,或是 schema free,  real-time 等等)。

Elasticsearch 的目標就是為了解決這些問題,甚至是更多 (做分析等等)。能夠做到類似事情的分析系統除了它之外,也有一套叫做 Solr,兩種都是 Apache Lecene 的骨子。

Elasticsearch 的優點像是安裝簡單, Model 是基於 JSON, Schema free (自由的搜尋模式) and Document Oriented,透過 HTTP 使用 JSON 索引資料,實現多租戶 (Multi Tenant) ,以及分佈式可以對搜尋做 cluster 等等...。

想到 Elasticsearch 的話,就是開源 / RESTful 的搜尋引擎 / Distributed (分佈式的),一言以蔽之,就是 A Distributed RESTful Search Engine

可以透過以下的 git repo 跟網址了解更多關於 Elasticsearch:




Getting Start
剛開始研究 Elasticsearch 時會有很多專有名詞的疑惑,在來是使用 Elasticsearch 要搭配 Java 的環境。





Mac 上安裝 Elasticsearch
github 上的說明寫到安裝的步驟其實很簡單:

  1. 到 elasticsearch.org 下載安裝檔,依照你的系統是什麼選擇需要的安裝方式
  2. 解壓縮之後執行 bin/elasticsearch 
    1. Unix 系統就執行 bin/elasticsearch
    2. Windows 系統執行bin/elasticsearch.bat
我是在 Mac 上裝 Elasticsearch,執行時 ./bin/elasticsearch,出現 『Exception in thread "main" java.lang.UnsupportedClassVersionError』 錯誤, 在 command line 輸入 java 指令後發現其實是我還沒裝 Java (我是安裝 JDK8 jdk-8u5-macosx-x64.dmg) :P。

安裝了 Java  之後,回到 elasticsearch-1.2.1 的資料夾再次執行 ./bin/elasticsearch,這下子就正常了(started): 
(你也可以考慮把 elasticsearch 跑在 background,ex: ./bin/elasticsearch -f)


Start 之後會開 9200 port。
最後, curl -X GET http://localhost:9200/,可以看到回傳的一個 JSON,一樣也能夠用 browser 訪問 localhost:9200。
Note: 如果想要換 port 的話,可以修改 elasticsearch-1.2.1/config/elasticsearch.yml 設定檔的 http.port: 9200,記得重啟 Elasticsearch。

恩,我起了 localhost:9200,然後呢?


接下來要看的就是使用 API 跟 elasticsearch 溝通,但官方文件很愛用 curl,如果不常用 curl 的話,你可以選擇其他的工具作為 Restful 跟 Elasticsearch 的接口,像是 Fiddler,而像我是用 chrome 的話,使用的是 Advance Rest Client 或是 POSTMAN


Github 上幾個例子,用幾種 HTTP Method,操作新增 index,新增資料,搜尋等等,在操作 CURD 時,REST API 大概會是像這樣: http://localhost:9200/<index>/<type>/[<id>]

  •  Index 跟 Type 是必要的
  •  id 為可選的 (即便沒有寫,會自動產生)(但如果不指定 id 應該要用 PUT 取代 POST)


Note: 像我平常是使用 MySQL,這裡指的 index 類似 MySQL 的 Database,我有上網爬了一下文章, MySQL 跟 Elasticsearch 的對應關係大概是這樣 :




1. 建立索引 (Index)
curl -XPUT 'http://localhost:9200/twitter/user/winwu' -d '{ "name" : "小 穎穎" }'
比方說我們執行這個 PUT 的 method,建立一個 twitter 的使用者 (winwu),elasticsearch 就會自動建立這個 twitter 的索引 (index)。

執行後回傳這樣的內容:

 {
      "_index":"twitter",
      "_type":"user",
      "_id":"winwu",
      "_version":1,
      "created":true
}

curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '
{
    "user": "winwu",
    "postDate": "2009-11-15T13:12:00",
    "message": "今天要做什麼呢"
}'
建立 id 為 1 的 tweet 內容,發文的 user 是 winwu,時間跟訊息。

執行後會回傳這樣的內容:

{
      "_index":"twitter",
      "_type":"tweet",
      "_id":"1",
      "_version":1,
      "created":true
}



2. GET 取得資料
curl -XGET 'http://localhost:9200/twitter/user/winwu?pretty=true'
這是取得 user 是 winwu 的資料,回傳 JSON

{
  "_index" : "twitter",
  "_type" : "user",
  "_id" : "winwu",
  "_version" : 1,
  "found" : true,
  "_source":{ "name" : "小 穎穎" }
}


curl -XGET 'http://localhost:9200/twitter/tweet/1?pretty=true'
這是取得 id 為 1 的 tweet 內容,回傳 JSON

{
    "_index": "twitter",
    "_type": "tweet",
    "_id": "1",
    "_version": 1,
    "found": true,
    "_source": {
        "user": "winwu",
        "postDate": "2009-11-15T13:12:00",
        "message": "今天要做什麼呢"
    }
}



3. Search 搜尋
搜尋可以用 GET,直接帶 Query String 在網址上,也能夠使用 JSON Query Language 進行搜尋。

搜尋所有 winwu 的推文:
curl -XGET 'http://localhost:9200/twitter/tweet/_search?q=user:winwu&pretty=true'

用 JSON Query Language 的表達方式:
curl -XGET 'http://localhost:9200/twitter/tweet/_search?pretty=true' -d ' {
     "query" : {
          "match" : { "user": "winwu" }
      }
}'

搜索結果:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 1.4054651,
    "hits" : [ {
      "_index" : "twitter",
      "_type" : "tweet",
      "_id" : "1",
      "_score" : 1.4054651,
      "_source":
{
    "user": "winwu",
    "postDate": "2009-11-15T13:12:00",
    "message": "今天要做什麼呢"
}
    }, {
      "_index" : "twitter",
      "_type" : "tweet",
      "_id" : "3",
      "_score" : 0.30685282,
      "_source":
{
    "user": "winwu",
    "postDate": "2014-07-06T13:12:00",
    "message": "我點了一杯桂花蘋果茶"
}
    }, {
      "_index" : "twitter",
      "_type" : "tweet",
      "_id" : "2",
      "_score" : 0.30685282,
      "_source":
{
    "user": "winwu",
    "postDate": "2014-07-06T13:12:00",
    "message": "我買了一把烏克麗麗"
}
    } ]
  }
}
搜尋有很多種變化,這個就要看看文件了。

Elasticsearch 有個概念叫做多租戶,簡單來說就是可以跨越好幾個索引 (index) 進行搜尋。


參考



8 則留言:

  1. 溫馨提醒
    不指定id要用POST取代PUT
    應該是筆誤了

    回覆刪除
    回覆
    1. 哦感謝啊!

      抱歉啊.. 確實是真的忘了,後來也沒有真的用到 elastic search 改用 aws 的 cloudsearch 了..

      刪除
  2. http://wsgzao.github.io/post/elk/?utm_content=bufferf8c72&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer 這裏也有一篇

    回覆刪除
  3. 感恩感恩 開始學習您的文章是我閱讀的第一篇!!

    回覆刪除

若你看的文章,時間太久遠的問題就別問了,因為我應該也忘了... XD

Vue multiselect set autofocus and tinymce set autofocus

要在畫面一進來 focus multiselect 的方式: 參考: https://jsfiddle.net/shentao/mnphdt2g/ 主要就是在 multiselect 的 tag 加上 ref (例如: my_multiselect), 另外在 mounted...