1. 程式人生 > >ElasticSearch 2.x入門與快速實踐

ElasticSearch 2.x入門與快速實踐

Introduction

ElasticSearch是一個基於Apache Lucene(TM)的開源搜尋引擎。無論在開源還是專有領域,Lucene可以被認為是迄今為止最先進、效能最好的、功能最全的搜尋引擎庫。但是,Lucene只是一個庫。想要使用它,你必須使用Java來作為開發語言並將其直接整合到你的應用中,更糟糕的是,Lucene非常複雜,你需要深入瞭解檢索的相關知識來理解它是如何工作的。ElasticSearch也使用Java開發並使用Lucene作為其核心來實現所有索引和搜尋的功能,但是它的目的是通過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜尋變得簡單。
不過,Elasticsearch不僅僅是Lucene和全文搜尋,我們還能這樣去描述它:

  • 分散式的實時檔案儲存,每個欄位都被索引並可被搜尋
  • 分散式的實時分析搜尋引擎
  • 可以擴充套件到上百臺伺服器,處理PB級結構化或非結構化資料

而且,所有的這些功能被整合到一個服務裡面,你的應用可以通過簡單的RESTful API、各種語言的客戶端甚至命令列與之互動。上手Elasticsearch非常容易。它提供了許多合理的預設值,並對初學者隱藏了複雜的搜尋引擎理論。它開箱即用(安裝即可使用),只需很少的學習既可在生產環境中使用。在ElasticSearch中,我們常常會聽到Index、Type以及Document等概念,那麼它們與傳統的熟知的關係型資料庫中名稱的類比如下:

Relational DB 
->Databases->Tables->Rows->ColumnsElasticsearch->Indices->Types->Documents->Fields

這裡借用此文的一張思維腦圖來描述整個ElasticSearch生態圈你所應該瞭解的內容:

Reference

Books & Tutorial

Quick Start

Installation

這裡下載ElasticSearch的最新預編譯版本,然後直接解壓縮啟動即可。筆者此時使用的是2.3.5版本的ElasticSearch,其檔案目錄結構如下:

home---這是
Elasticsearch解壓的目錄
  bin---這裡面是ES啟動的指令碼   conf---elasticsearch.ymlES的配置檔案   data---這裡是ES得當前節點的分片的資料,可以直接拷貝到其他的節點進行使用   logs---日誌檔案   plugins---這裡存放一些常用的外掛,如果有一切額外的外掛,可以放在這裡使用。

在ElasticSearch 2.x版本中,預設是不允許以Root使用者身份執行例項,可以使用bin/elasticsearch -Des.insecure.allow.root=true來以Root身份啟動叢集,此外還可以使用bin/elasticsearch -f -Des.path.conf=/path/to/config/dir引數來讀取相關的.yml或者.json配置。

還有些常見的配置如下所示:

Setting Description
http.port A bind port range. Defaults to 9200-9300.
http.publish_port The port that HTTP clients should use when communicating with this node. Useful when a cluster node is behind a proxy or firewall and the http.port is not directly addressable from the outside. Defaults to the actual port assigned via http.port.
http.bind_host The host address to bind the HTTP service to. Defaults to http.host(if set) ornetwork.bind_host.
http.publish_host The host address to publish for HTTP clients to connect to. Defaults to http.host (if set) ornetwork.publish_host.
http.host Used to set the http.bind_host and the http.publish_host Defaults tohttp.host ornetwork.host.
http.max_content_length The max content of an HTTP request. Defaults to 100mb. If set to greater thanInteger.MAX_VALUE, it will be reset to 100mb.
http.max_initial_line_length The max length of an HTTP URL. Defaults to 4kb
http.max_header_size The max size of allowed headers. Defaults to 8kB
http.compression Support for compression when possible (with Accept-Encoding). Defaults to false.
http.compression_level Defines the compression level to use. Defaults to 6.
http.cors.enabled Enable or disable cross-origin resource sharing, i.e. whether a browser on another origin can do requests to Elasticsearch. Defaults to false.
http.cors.allow-origin Which origins to allow. Defaults to no origins allowed. If you prepend and append a / to the value, this will be treated as a regular expression, allowing you to support HTTP and HTTPs. for example using/https?:\/\/localhost(:[0-9]+)?/ would return the request header appropriately in both cases. *is a valid value but is considered asecurity risk as your elasticsearch instance is open to cross origin requests fromanywhere.
http.cors.max-age Browsers send a “preflight” OPTIONS-request to determine CORS settings. max-agedefines how long the result should be cached for. Defaults to 1728000 (20 days)
http.cors.allow-methods Which methods to allow. Defaults to OPTIONS, HEAD, GET, POST, PUT, DELETE.
http.cors.allow-headers Which headers to allow. Defaults to X-Requested-With, Content-Type, Content-Length.
http.cors.allow-credentials Whether the Access-Control-Allow-Credentials header should be returned. Note: This header is only returned, when the setting is set to true. Defaults to false
http.detailed_errors.enabled Enables or disables the output of detailed error messages and stack traces in response output. Note: When set to false and theerror_trace request parameter is specified, an error will be returned; whenerror_trace is not specified, a simple message will be returned. Defaults to true
http.pipelining Enable or disable HTTP pipelining, defaults to true.
http.pipelining.max_events The maximum number of events to be queued up in memory before a HTTP connection is closed, defaults to 10000.

REST API

在我們啟動了某個ElasticSearch例項之後,即可以通過ElasticSearch自帶的基於JSON REST API來進行互動。我們可以使用官方教程中提供的curl工具,或者稍微複雜一點的常用工具Fiddler或者RESTClient來進行互動,不過這裡推薦使用Sense,這是Chrome內建的一個外掛,能夠提供很多的ElasticSearch的自動補全功能。


當我們直接訪問根目錄時,會得到如下的提示:

{"name":"Mister Fear","cluster_name":"elasticsearch","version":{"number":"2.3.5","build_hash":"90f439ff60a3c0f497f91663701e64ccd01edbb4","build_timestamp":"2016-07-27T10:36:52Z","build_snapshot":false,"lucene_version":"5.5.0"},"tagline":"You Know, for Search"}

CRUD

Index:建立與更新索引

在ElasticSearch中,Index這一動作類比於CRUD中的Create與Update,當我們嘗試為某個不存在的文件建立索引時,會自動根據其類似與ID建立新的文件,否則就會對原有的文件進行修改。ElasticSearch使用PUT請求來進行Index操作,你需要提供索引名稱、型別名稱以及可選的ID,格式規範為:http://localhost:9200/<index>/<type>/[<id>]。其中索引名稱可以是任意字元,如果ElasticSearch中並不存在該索引則會自動建立。型別名的原則很類似於索引,不過其與索引相比會指明更多的細節資訊:

  • 每個型別有自己獨立的ID空間
  • 不同的型別有不同的對映(Mappings),即不同的屬性/域的建立索引的方案
  • 儘可能地在一起搜尋請求中只對某個型別或者特定的型別進行搜尋

典型的某個Index請求為:

curl -XPUT "http://localhost:9200/movies/movie/1"-d'
{
    "title": "The Godfather",
    "director": "Francis Ford Coppola",
    "year": 1972
}'

在上述請求執行之後,ElasticSearch會為我們建立索引名為Movies,型別名為Movie,ID為1的文件。當然你也可以在Sense中執行該請求,這樣的話使用者體驗會更好一點:

在上圖中我們可以瞭解到,ElasticSearch對於PUT請求的響應中包含了是否操作成功、文件編號等資訊。此時我們如果進行預設的全域性搜尋,可以得到如下返回:

可以看出我們剛剛新建的文件已經可以被查詢,接下來我們嘗試對剛才新建立的文件進行些修改,新增某些關鍵字屬性。我們同樣可以利用PUT請求來進行該操作,不過我們這次務必要加上需要修改的文件的ID編號:

curl -XPUT "http://localhost:9200/movies/movie/1"-d'
{
    "title": "The Godfather",
    "director": "Francis Ford Coppola",
    "year": 1972,
    "genres": ["Crime", "Drama"]
}'

對於此操作的ElasticSearch的響應與前者很類似,不過會可以看出_version屬性值已經發生了變化:

該屬性即是用來追蹤文件被修改過的次數,可以在樂觀併發控制策略中控制併發修改,ElasticSearch僅會允許版本號高於原文件版本號的修改發生。

GET

最簡單的獲取某個文件的方式即是基於文件ID進行搜尋,標準的請求格式為:http://localhost:9200/<index>/<type>/<id>,我們查詢下上文中插入的一些電影資料:

curl-XGET "http://localhost:9200/movies/movie/1"-d''


返回資料中同樣會包含版本資訊、ID編號以及源資訊。

Delete:刪除索引

現在我們嘗試去刪除上文中插入的部分文件,對於要刪除的文件同樣需要傳入索引名、型別名與文件名這些資訊,譬如:

curl-XDELETE "http://localhost:9200/movies/movie/1"-d''


在我們刪除了該文件之後,再次嘗試用GET方法獲取該文件資訊時,會得到如下的響應:

Search

ElasticSearch最誘人的地方即是為我們提供了方便快捷的搜尋功能,我們首先嚐試使用如下的命令建立測試文件:

curl -XPUT "http://localhost:9200/movies/movie/1"-d'
{
    "title": "The Godfather",
    "director": "Francis Ford Coppola",
    "year": 1972,
    "genres": ["Crime", "Drama"]
}'

curl -XPUT "http://localhost:9200/movies/movie/2"-d'
{
    "title": "Lawrence of Arabia",
    "director": "David Lean",
    "year": 1962,
    "genres": ["Adventure", "Biography", "Drama"]
}'

curl -XPUT "http://localhost:9200/movies/movie/3"-d'
{
    "title": "To Kill a Mockingbird",
    "director": "Robert Mulligan",
    "year": 1962,
    "genres": ["Crime", "Drama", "Mystery"]
}'

curl -XPUT "http://localhost:9200/movies/movie/4"-d'
{
    "title": "Apocalypse Now",
    "director": "Francis Ford Coppola",
    "year": 1979,
    "genres": ["Drama", "War"]
}'

curl -XPUT "http://localhost:9200/movies/movie/5"-d'
{
    "title": "Kill Bill: Vol. 1",
    "director": "Quentin Tarantino",
    "year": 2003,
    "genres": ["Action", "Crime", "Thriller"]
}'

curl -XPUT "http://localhost:9200/movies/movie/6"-d'
{
    "title": "The Assassination of Jesse James by the Coward Robert Ford",
    "director": "Andrew Dominik",
    "year": 2007,
    "genres": ["Biography", "Crime", "Drama"]
}'

這裡需要了解的是,ElasticSearch為我們提供了通用的_bulk端點來在單請求中完成多文件建立操作,不過這裡為了簡單起見還是分為了多個請求進行執行。ElasticSearch中搜索主要是基於_search這個端點進行的,其標準請求格式為:<index>/<type>/_search,其中index與type都是可選的。換言之,我們可以以如下幾種方式發起請求:

全文搜尋

ElasticSearch的Query DSL為我們提供了許多不同型別的強大的查詢的語法,其核心的查詢字串包含很多查詢的選項,並且由ElasticSearch編譯轉化為多個簡單的查詢請求。最簡單的查詢請求即是全文檢索,譬如我們這裡需要搜尋關鍵字:kill:

curl