elasticsearch入門使用

該文章基於:http://blog.csdn.net/gl775307284/article/details/44731009 整理而來javascript

基礎概念

一、接近實時(NRT)
Elasticsearch是一個接近實時的搜索平臺。這意味着,從索引一個文檔直到這個文檔可以被搜索到有一個輕微的延遲(一般是1秒)html

二、集羣(cluster)
一個集羣就是由一個或多個節點組織在一塊兒,它們共同持有你整個的數據,並一塊兒提供索引和搜索功能。
一個集羣由一個惟一的名字標識,這個名字默認就是 「elasticsearch」。
這個名字是重要的,由於一個節點只能經過指定某個集羣的名字,來加入這個集羣。
在產品環境中顯式地設定這個名字是一個好習慣,可是使用默認值來進行測試/開發也是不錯的。java

三、節點(node)
一個節點是你集羣中的一個服務器,做爲集羣的一部分,它存儲你的數據,參與集羣的索引和搜索功能。
和集羣相似,一個節點也是由一個名字來標識的,默認狀況 下,這個名字是一個隨機的漫威漫畫角色的名字,
這個名字會在啓動的時候賦予節點。這個名字對於管理工做來講挺重要的,由於在這個管理過程當中,
你會去肯定網 絡中的哪些服務器對應於Elasticsearch集羣中的哪些節點。
一個節點能夠經過配置集羣名稱的方式來加入一個指定的集羣。
默認狀況下,每一個節點都會被安排加入到一個叫作「elasticsearch」的集羣中,這意 味着,
若是你在你的網絡中啓動了若干個節點,並假定它們可以相互發現彼此,它們將會自動地造成並加入到一個叫作「elasticsearch」的集羣中。
在一個集羣裏,只要你想,能夠擁有任意多個節點。並且,若是當前你的網絡中沒有運行任何Elasticsearch節點,
這時啓動一個節點,會默認建立並加入一個叫作「elasticsearch」的集羣。node

四、索引(index)
一個索引就是一個擁有幾分類似特徵的文檔的集合。好比說,你能夠有一個客戶數據的索引,另外一個產品目錄的索引,還有一個訂單數據的索引。
一個索引由一個名 字來標識(必須所有是小寫字母的),而且當咱們要對對應於這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字。
在一個集羣中,若是你想,能夠定義任意多的索引。git

五、類型(type)
在一個索引中,你能夠定義一種或多種類型。一個類型是你的索引的一個邏輯上的分類/分區,其語義徹底由你來定。
一般,會爲具備一組共同字段的文檔定義一個 類型。好比說,咱們假設你運營一個博客平臺而且將你全部的數據存儲到一個索引中。
在這個索引中,你能夠爲用戶數據定義一個類型,爲博客數據定義另外一個類 型,固然,也能夠爲評論數據定義另外一個類型。github

六、文檔(document)
一個文檔是一個可被索引的基礎信息單元。好比,你能夠擁有某一個客戶的文檔,某一個產品的一個文檔,
固然,也能夠擁有某個訂單的一個文檔。文檔以 JSON(Javascript Object Notation)格式來表示,而JSON是一個處處存在的互聯網數據交互格式。
在一個index/type裏面,只要你想,你能夠存儲任意多的文檔。注意,儘管一個文檔,物理上存在於一個索引之中,文檔必須被索引/賦予一個索引的type。json

七、分片和複製(shards & replicas)
  • 一個索引能夠存儲超出單個結點硬件限制的大量數據。好比,一個具備10億文檔的索引佔據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢。    爲了解決這個問題,Elasticsearch提供了將索引劃分紅多份的能力,這些份就叫作分片。 當你建立一個索引的時候,你能夠指定你想要的分片的數量。每一個分片自己也是一個功能完善而且獨立的「索引」,這個「索引」能夠被放置到集羣中的任何節點上。
  • 分片之因此重要,主要有兩方面的緣由:

- 容許你水平分割/擴展你的內容容量windows

- 容許你在分片(潛在地,位於多個節點上)之上進行分佈式的、並行的操做,進而提升性能/吞吐量api

  •  至於一個分片怎樣分佈,它的文檔怎樣聚合回搜索請求,是徹底由Elasticsearch管理的,對於做爲用戶的你來講,這些都是透明的
  • 在一個網絡/雲的環境裏,失敗隨時均可能發生,在某個分片/節點不知怎麼的就處於離線狀態,或者因爲任何緣由消失了,這種狀況下,有一個故障轉移機制是非 常有用而且是強烈推薦的。爲此目的,Elasticsearch容許你建立分片的一份或多份拷貝,這些拷貝叫作複製分片,或者直接叫複製。
  • 複製之因此重要,有兩個主要緣由:

- 在分片/節點失敗的狀況下,提供了高可用性。由於這個緣由,注意到複製分片從不與原/主要(original/primary)分片置於同一節點上是很是重要的。瀏覽器

- 擴展你的搜索量/吞吐量,由於搜索能夠在全部的複製上並行運行

  • 總之,每一個索引能夠被分紅多個分片。一個索引也能夠被複制0次(意思是沒有複製)或屢次。一旦複製了,每一個索引就有了主分片(做爲複製源的原來的分片)和 複製分片(主分片的拷貝)之別。分片和複製的數量能夠在索引建立的時候指定。在索引建立以後,你能夠在任什麼時候候動態地改變複製的數量,可是你過後不能改變 分片的數量。
  • 默認狀況下,Elasticsearch中的每一個索引被分片5個主分片和1個複製,這意味着,若是你的集羣中至少有兩個節點,你的索引將會有5個主分片和另外5個複製分片(1個徹底拷貝),這樣的話每一個索引總共就有10個分片。

安裝

一、環境:JDK使用java 1.8(安裝省略),elasticsearch 2.3.4,window系統

二、下載解壓後,在bin目錄中運行elasticsearch.bat

此處的節點名稱:Vermin

咱們能夠覆蓋集羣或者節點的名字。咱們能夠在啓動Elasticsearch的時候經過命令行來指定,以下:
elasticsearch.bat --cluster.name my_cluster_name --node.name my_node_name

 

三、提供了有關HTTP地址(192.168.8.112)和端口(9200)的信息,經過這個地址和端口咱們就能夠 訪問咱們的節點了。
默認狀況下,Elasticsearch使用9200來提供對其REST API的訪問。若是有必要,這個端口是能夠配置的

訪問地址:http://127.0.0.1:9200/

 

利用rest api通訊

  • 檢查你的集羣、節點和索引的健康狀態、和各類統計信息
  • 管理你的集羣、節點、索引數據和元數據
  • 對你的索引進行CRUD(建立、讀取、更新和刪除)和搜索操做
  • 執行高級的查詢操做,像是分頁、排序、過濾、腳本編寫(scripting)、小平面刻畫(faceting)、聚合(aggregations)和許多其它操做

爲了方便在對elasticsearch通訊,安裝插件sense,因爲google被牆,沒法訪問Google 商店,所以建議使用360瀏覽器安裝sense插件,安裝方法(略)

 

一、集羣健康

訪問的URL: [html]  view plain  copy
  1. http://127.0.0.1:9200/_cat/health?v  
響應: [html]  view plain  copy
  1. epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent   
  2. 1512722087 16:34:47  elasticsearch green           1         1      0   0    0    0        0             0                  -                100.0%   
  • 集羣的名字是「elasticsearch」,正常運行,而且狀態是綠色。

(1)當咱們詢問集羣狀態的時候,咱們要麼獲得綠色、黃色或紅色

綠色表明一切正常(集羣功能齊全)

黃色意味着全部的數據都是可用的,可是某些複製沒有被分配 (集羣功能齊全)

紅色則表明由於某些緣由,某些數據不可用。注意,即便是集羣狀態是紅色的,集羣仍然是部分可用的(它仍然會利用可用的分片來響應搜索請 求),可是可能你須要儘快修復它,由於你有丟失的數據。

(2)從上面的響應中,咱們能夠看到,一共有一個節點,因爲裏面沒有數據,咱們有0個分片。注意,因爲咱們使用默認的集羣名字 (elasticsearch),而且因爲Elasticsearch默認使用網絡多播(multicast)發現其它節點,若是你在你的網絡中啓動了多 個節點,你就已經把她們加入到一個集羣中了。在這種情形下,你可能在上面的響應中看到多個節點。

二、列出節點列表

訪問的URL(GET請求):

 

[html] view plain copy

  1. http://127.0.0.1:9200/_cat/nodes?v  
響應:

 

[html] view plain copy

  1. host      ip        heap.percent ram.percent  load node.role master name        
  2. 127.0.0.1 127.0.0.1            7          63 -1.00 d         *      Mary Zero   
從中能夠看到節點是Mary Zero

 

三、列出全部的索引

訪問的URL(GET請求):

 

[html] view plain copy

  1. http://127.0.0.1:9200/_cat/indices?v  
響應:

 

[html] view plain copy

  1. health status index pri rep docs.count docs.deleted store.size pri.store.size   
從中能夠看到尚未索引

 

四、建立一個索引

建立一個叫「customer」的索引

訪問地址,使用sense插件請求(PUT請求):

 

[html] view plain copy

  1. 127.0.0.1:9200/customer?pretty  
響應:

 

[html] view plain copy

  1. {  
  2.    "acknowledged": true  
  3. }  
因爲加入了pretty在尾部,會打印出美觀的json形式

列出全部索引(參考 3)

 

[html] view plain copy

  1. health status index    pri rep docs.count docs.deleted store.size pri.store.size   
  2. yellow open   customer   5   1          0            0       650b           650b   

這個customer索引有一個黃色健康標籤。回顧咱們以前的討論,黃色意味着某些複製沒有(或者還未)被分配。這個索引之因此這樣,是 由於Elasticsearch默認爲這個索引建立一份複製。因爲如今咱們只有一個節點在運行,那一份複製就分配不了了(爲了高可用),直到當另一個節 點加入到這個集羣后,才能分配。一旦那份複製在第二個節點上被複制,這個節點的健康狀態就會變成綠色。

索引並查詢文檔

 

利用以前建立的customer索引進行相關文檔操做,使用sense插件,server:127.0.0.1:9200

首先要知道的是,爲了索引一個文檔,咱們必須告訴Elasticsearch這個文檔要到這個索引的哪一個類型(type)下。

 

一、將一個簡單的客戶文檔索引到customer索引、「external」類型中,這個文檔的ID是1

 

[html]  view plain  copy
  1. PUT /customer/external/1?pretty  
  2. {  
  3.     "name":"Johe Done"  
  4. }  
響應:

 

 

[html]  view plain  copy
  1. {  
  2.    "_index": "customer",  
  3.    "_type": "external",  
  4.    "_id": "1",  
  5.    "_version": 1,  
  6.    "_shards": {  
  7.       "total": 2,  
  8.       "successful": 1,  
  9.       "failed": 0  
  10.    },  
  11.    "created": true  
  12. }  
從上面的響應中,咱們能夠看到,一個新的客戶文檔在customer索引和external類型中被成功建立。文檔也有一個內部id 1, 這個id是咱們在索引的時候指定的。
有一個關鍵點須要注意,Elasticsearch在你想將文檔索引到某個索引的時候,並不強制要求這個索引被顯式地建立。
在前面這個例子中,若是customer索引不存在,Elasticsearch將會自動地建立這個索引。

 

二、取出建立的文檔

 

[html]  view plain  copy
  1. GET /customer/external/1?pretty  

響應:

 

 

[html]  view plain  copy
  1. {  
  2.    "_index": "customer",  
  3.    "_type": "external",  
  4.    "_id": "1",  
  5.    "_version": 2,  
  6.    "found": true,  
  7.    "_source": {  
  8.       "name": "Johe Done"  
  9.    }  
  10. }  

三、刪除建立的索引

 

 

[html]  view plain  copy
  1. DELETE /customer?pretty  
響應:

 

 

[html]  view plain  copy
  1. {  
  2.    "acknowledged": true  
  3. }  
在查看索引(參考 :列出全部索引)

 

響應:

 

[html]  view plain  copy
  1. health status index pri rep docs.count docs.deleted store.size pri.store.size   
這代表咱們成功地刪除了這個索引,如今咱們回到了集羣中空無全部的狀態

 

 

四、修改數據

Elasticsearch提供了近乎實時的數據操做和搜索功能。默認狀況下,從你索引/更新/刪除你的數據動做開始到它出如今你的搜索結果中,

大概會有1秒鐘的延遲。這和其它相似SQL的平臺不一樣,數據在一個事務完成以後就會當即可用。

先添加ID:1,name:Johe Done

 

[html]  view plain  copy
  1. PUT /customer/external/1?pretty  
  2. {  
  3.     "name":"Johe Done"  
  4. }  

 

在添加ID:2,name:Loren

 

[html]  view plain  copy
  1. PUT /customer/external/2?pretty  
  2. {  
  3.     "name":"Loren"  
  4. }  
在索引的時候,ID部分是可選的。若是不指定,Elasticsearch將產生一個隨機的ID來索引這個文檔。Elasticsearch生成的ID會做爲索引API調用的一部分被返回。

 

 

[html]  view plain  copy
  1. POST /customer/external?pretty  
  2. {  
  3.     "name":"Karrt"  
  4. }  
在上面的情形中,因爲咱們沒有指定一個ID,咱們使用的是POST而不是PUT。

 


五、更新文檔

除了能夠索引、替換文檔以外,咱們也能夠更新一個文檔。但要注意,Elasticsearch底層並不支持原地更新。在咱們想要作一次更新的時候,Elasticsearch先刪除舊文檔,而後在索引一個更新過的新文檔。

將name的值修改成Lucene

 

[html]  view plain  copy
  1. POST /customer/external/1/_update?pretty  
  2. {  
  3.     "doc":{"name":"Lucene"}  
  4. }  

將name的值修改,並同時添加age字段

 

 

[html]  view plain  copy
  1. POST /customer/external/1/_update?pretty  
  2. {  
  3.     "doc":{"name":"Lucene", "age":50}  
  4. }  
使用腳本將age加10

 

 

[html]  view plain  copy
  1. POST /customer/external/1/_update?pretty  
  2. {  
  3.     "script":"ctx._source.age += 10"  
  4. }  

 

ctx._source指向當前要被更新的文檔。

須要開啓容許腳本運行

 

在elasticsearch.yml配置文件中添加

 

[html] view plain copy

  1. script.inline: on    
  2. script.indexed: on   
  3. script.engine.groovy.inline.aggs: on   

 

 

六、刪除文檔

刪除ID:2的文檔

 

[html] view plain copy

  1. DELETE /customer/external/2?pretty  
經過查詢刪除多個文檔,例如:刪除name包含Kerry的文檔

 

[html] view plain copy

  1. DELETE /customer/external/_query?pretty  
  2. {  
  3.     "query":{"match": {  
  4.        "name": "Kerry"  
  5.     }}  
  6. }  
注意:在2.x以上版本默認的的Delete by Query API被移除,須要本身按照插件,緣由: https://www.elastic.co/blog/core-delete-by-query-is-a-plugin
在bin目錄運行:

 

[html] view plain copy

  1. plugin.bat install delete-by-query  
 集羣環境下必須在每一個結點上安裝,安裝以後要重啓結點才能使這個插件生效

 

七、批處理

除了可以對單個的文檔進行索引、更新和刪除以外,Elasticsearch也提供了以上操做的批量處理功能,這是經過使用_bulk API實現的。

這個功能之因此重要,在於它提供了很是高效的機制來儘量快的完成多個操做,與此同時使用盡量少的網絡往返。

批量修改ID:1,ID:2的數據

 

[html]  view plain  copy
  1. POST /customer/external/_bulk?pretty  
  2. {"index":{"_id":"2"}}  
  3. {"name":"kkkkk"}  
  4. {"index":{"_id":"1"}}  
  5. {"name":"enenen"}  

 

 

先修改(ID:1),在刪除ID:3

 

[html]  view plain  copy
  1. POST /customer/external/_bulk?pretty  
  2. {"update":{"_id":"1"}}  
  3. {"doc":{"name":"zhangsan"}}  
  4. {"delete":{"_id":"3"}}  
注意上面的delete動做,因爲刪除動做只須要被刪除文檔的ID,因此並無對應的源文檔

 

bulk API按順序執行這些動做。若是其中一個動做由於某些緣由失敗了,將會繼續處理它後面的動做。當bulk API返回時,它將提供每一個動做的狀態(按照一樣的順序),因此你可以看到某個動做成功與否。

 

例子學習

一、樣本數據集

以客戶的銀行帳戶信息的JSON文檔的樣本。文檔具備如下的模式(schema)

 

[javascript]  view plain  copy
  1. {  
  2.     "account_number": 0,  
  3.     "balance": 16623,  
  4.     "firstname": "Bradshaw",  
  5.     "lastname": "Mckenzie",  
  6.     "age": 29,  
  7.     "gender": "F",  
  8.     "address": "244 Columbus Place",  
  9.     "employer": "Euron",  
  10.     "email": "bradshawmckenzie@euron.com",  
  11.     "city": "Hobucken",  
  12.     "state": "CO"  
  13. }  

二、載入樣本數據

樣本數據獲取:https://github.com/bly2k/files/blob/master/accounts.zip?raw=true

本人不知道如何使用sense讀取本地json文件,所以使用GUI bash工具在windows使用curl命令

 

[javascript]  view plain  copy
  1. curl -XPOST '127.0.0.1:9200/bank/account/_bulk?pretty' --data-binary @accounts.json  
查看索引

 

 

[javascript]  view plain  copy
  1. GET /_cat/indices?v  
[html]  view plain  copy
  1. health status index    pri rep docs.count docs.deleted store.size pri.store.size   
  2. yellow open   bank       5   1       1000            0    442.1kb        442.1kb   
  3. yellow open   customer   5   1          3            0      9.4kb          9.4kb   
 

三、搜索API

經過‘_search’來查詢調用,而且q=*參數指示Elasticsearch去匹配這個索引中全部的文檔。pretty參數,和之前同樣,僅僅是告訴Elasticsearch返回美觀的JSON結果

 

[html]  view plain  copy
  1. GET /bank/_search?q=*&pretty  
部分響應:

 

[html]  view plain  copy
  1. {  
  2.    "took": 58,  
  3.    "timed_out": false,  
  4.    "_shards": {  
  5.       "total": 5,  
  6.       "successful": 5,  
  7.       "failed": 0  
  8.    },  
  9.    "hits": {  
  10.       "total": 1000,  
  11.       "max_score": 1,  
  12.       "hits": [  
  13.          {  
  14.             "_index": "bank",  
  15.             "_type": "account",  
  16.             "_id": "25",  
  17.             "_score": 1,  
  18.             "_source": {  
  19.                "account_number": 25,  
  20.                "balance": 40540,  
  21.                "firstname": "Virginia",  
  22.                "lastname": "Ayala",  
  23.                "age": 39,  
  24.                "gender": "F",  
  25.                "address": "171 Putnam Avenue",  
  26.                "employer": "Filodyne",  
  27.                "email": "virginiaayala@filodyne.com",  
  28.                "city": "Nicholson",  
  29.                "state": "PA"  
  30.             }  
  31.          },  
  32.          {  
  33.             "_index": "bank",  
  34.             "_type": "account",  
  35.             "_id": "44",  
  36.             "_score": 1,  
  37.             "_source": {  
  38.                "account_number": 44,  
  39.                "balance": 34487,  
  40.                "firstname": "Aurelia",  
  41.                "lastname": "Harding",  
  42.                "age": 37,  
  43.                "gender": "M",  
  44.                "address": "502 Baycliff Terrace",  
  45.                "employer": "Orbalix",  
  46.                "email": "aureliaharding@orbalix.com",  
  47.                "city": "Yardville",  
  48.                "state": "DE"  
  49.             }  
  50.          },  
  51.          {  
  52.             "_index": "bank",  
  53.             "_type": "account",  
  54.             "_id": "99",  
  55.             "_score": 1,  
  56.             "_source": {  
  57.                "account_number": 99,  
  58.                "balance": 47159,  
  59.                "firstname": "Ratliff",  
  60.                "lastname": "Heath",  
  61.                "age": 39,  
  62.                "gender": "F",  
  63.                "address": "806 Rockwell Place",  
  64.                "employer": "Zappix",  
  65.                "email": "ratliffheath@zappix.com",  
  66.                "city": "Shaft",  
  67.                "state": "ND"  
  68.             }  
  69.          },  
響應說明:

took:elasticsearch執行這個搜索的耗時,以毫秒爲單位

timed_out:指明這個搜索是否超時

_shards:指出多少個分片被搜索,同時也指出成功/失敗的被搜索的shareds數量

hits:搜索的結果

hits.total:可以匹配搜索出文檔的總數

hits.hits:真正搜索的數據,默認顯示10條

max_score和_score:先忽略

 

另外一種等價的方式:

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {"match_all": {}}  
  4. }  

這裏的不一樣之處在於,並非向URI中傳遞q=*,取而代之的是,咱們在_search API的請求體中POST了一個JSON格式請求體

有一點須要重點理解一下,一旦你取回了你的搜索結果,Elasticsearch就完成了使命,它不會維護任何服務器端的資源或者在你的結果中打開遊標。 這是和其它相似SQL的平臺的一個鮮明的對比, 在那些平臺上,你能夠在前面先獲取你查詢結果的一部分,而後若是你想獲取結果的剩餘部分,你必須繼續返回服務端去取,這個過程使用一種有狀態的服務器端遊 標技術。

 

四、介紹查詢語言

Elasticsearch提供一種JSON風格的特定領域語言,利用它你能夠執行查詢。這被稱爲查詢DSL。

 

[html]  view plain  copy
  1. {  
  2.     "query": {"match_all": {}}  
  3. }  
分解上面的這個查詢,其中的query部分告訴我查詢的定義,match_all部分就是咱們想要運行的查詢的類型。match_all查詢,就是簡單地查詢一個指定索引下的全部的文檔。

除了這個query參數以外,咱們也能夠經過傳遞其它的參數來影響搜索結果

例如只返回一個文檔

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {"match_all": {}},  
  4.     "size": 1  
  5. }  
size若是沒有指定,默認值是10

返回第11到20的文檔

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {"match_all": {}},  
  4.     "from": 11,   
  5.     "size": 10  
  6. }  
其中的from參數(0-based)從哪一個文檔開始,size參數指明從from參數開始,要返回多少個文檔。這個特性對於搜索結果分頁來講很是有幫助。注意,若是不指定from的值,它默認就是0

下面的例子:

搜索全部的帳戶並餘額降序排序,返回前10個文檔

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {"match_all": {}},  
  4.     "sort": [  
  5.        {  
  6.           "balance": {  
  7.              "order": "desc"  
  8.           }  
  9.        }  
  10.     ]  
  11. }  

五、執行搜索

如今咱們已經知道了幾個基本的參數,讓咱們進一步發掘查詢語言吧。首先咱們看一下返回文檔的字段。默認狀況下,是返回完整的JSON文檔的。這能夠經過 source來引用(搜索hits中的_source字段)。若是咱們不想返回完整的源文檔,咱們能夠指定返回的幾個字段。

返回指定的account_number和balance兩個 字段

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {"match_all": {}},  
  4.     "_source":["account_number", "balance"]  
  5. }  
上面的例子僅僅是簡化了_source字段。它仍將會返回一個叫作_source的字段,可是僅僅包含account_number和balance來年改革字段

 

咱們看到了match_all查詢是怎樣匹配到全部的文檔的。如今咱們介紹一種新的查詢,叫作match查詢,這能夠當作是一個簡單的字段搜索查詢(好比對應於某個或某些特定字段的搜索)

查詢account_number爲44的文檔

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {"match": {  
  4.        "account_number": 44  
  5.     }}  
  6. }  

 

搜索地址包含mill的文檔

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {"match": {  
  4.        "address": "mill"  
  5.     }}  
  6. }  

 

搜索地址包含mill或者lane的文檔

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {"match": {  
  4.        "address": "mill lane"  
  5.     }}  
  6. }  

下面這個例子是match的變體(match_phrase),它會去匹配短語「mill lane」:

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {  
  4.         "match_phrase": {  
  5.            "address": "mill lane"  
  6.         }  
  7.     }  
  8. }  

介紹一下布爾查詢。布爾查詢容許咱們利用布爾邏輯將較小的查詢組合成較大的查詢

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {  
  4.         "bool": {  
  5.             "must": [  
  6.                {"match": {  
  7.                   "address": "mill"  
  8.                }},  
  9.                {"match": {  
  10.                   "address": "lane"  
  11.                }}  
  12.             ]  
  13.         }  
  14.     }  
  15. }  

這個例子組合了兩個match查詢,這個組合查詢返回必須包含「mill」和「lane」的全部的帳戶

bool must語句指明瞭,對於一個文檔,全部的查詢都必須爲真,這個文檔纔可以匹配成功

 

相反的,下面的例子組合了兩個match查詢,它返回的是地址中包含「mill」或者「lane」的全部的帳戶

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {  
  4.         "bool": {  
  5.             "should": [  
  6.                {"match": {  
  7.                   "address": "mill"  
  8.                }},  
  9.                {"match": {  
  10.                   "address": "lane"  
  11.                }}  
  12.             ]  
  13.         }  
  14.     }  
  15. }  
bool should語句指明,對於一個文檔,查詢列表中,只要有一個查詢匹配,那麼這個文檔就被當作是匹配的

 

下面這個例子組合了兩個查詢,它返回地址中既不包含「mill」,同時也不包含「lane」的全部的帳戶信息

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {  
  4.         "bool": {  
  5.             "must_not": [  
  6.                {"match": {  
  7.                   "address": "mill"  
  8.                }},  
  9.                {"match": {  
  10.                   "address": "lane"  
  11.                }}  
  12.             ]  
  13.         }  
  14.     }  
  15. }  
在上面的例子中, bool must_not語句指明,對於一個文檔,查詢列表中的的全部查詢都必須都不爲真,這個文檔才被認爲是匹配的。
咱們能夠在一個bool查詢裏一塊兒使用must、should、must_not。此外,咱們能夠將bool查詢放到這樣的bool語句中來模擬複雜的、多等級的布爾邏輯。


下面的列子搜索出,age=40而且state不等於PA的文檔

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {  
  4.         "bool": {  
  5.             "must": [  
  6.                {"match": {  
  7.                   "age": 40  
  8.                }}  
  9.             ],  
  10.             "must_not": [  
  11.                {"match": {  
  12.                   "state": "PA"  
  13.                }}  
  14.             ]  
  15.         }  
  16.     }  
  17. }  

六、執行過濾器

在先前的章節中,咱們跳過了文檔得分的細節(搜索結果中的_score字段)。這個得分是與咱們指定的搜索查詢匹配程度的一個相對度量。得分越高,文檔越相關,得分越低文檔的相關度越低。


Elasticsearch中的全部的查詢都會觸發相關度得分的計算。對於那些咱們不須要相關度得分的場景下,Elasticsearch以過濾器的形式 提供了另外一種查詢功能。過濾器在概念上相似於查詢,可是它們有很是快的執行速度,這種快的執行速度主要有如下兩個緣由

 

  • 過濾器不會計算相關度的得分,因此它們在計算上更快一些
  • 過濾器能夠被緩存到內存中,這使得在重複的搜索查詢上,其要比相應的查詢快出許多

 

爲了理解過濾器,咱們先來介紹「被過濾」的查詢,這使得你能夠將一個查詢(像是match_all,match,bool等)和一個過濾器結合起來。

做爲一個例子,咱們介紹一下範圍過濾器,它容許咱們經過一個區間的值來過濾文檔。這一般被用在數字和日期的過濾上。

使用一個被過濾的查詢,其返回值是越在20000到30000之間(閉區間)的帳戶。換句話說,咱們想要找到越大於等於20000而且小於等於30000的帳戶

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "query": {  
  4.         "filtered": {  
  5.            "query": {"match_all": {}},  
  6.            "filter": {  
  7.                "range": {  
  8.                   "balance": {  
  9.                      "gte": 20000,  
  10.                      "lte": 30000  
  11.                   }  
  12.                }  
  13.            }  
  14.         }  
  15.     }  
  16. }  

分解上面的例子,被過濾的查詢包含一個match_all查詢(查詢部分)和一個過濾器(filter部分)。咱們能夠在查詢部分中放入其餘查詢,在 filter部分放入其它過濾器。在上面的應用場景中,因爲全部的在這個範圍以內的文檔都是平等的(或者說相關度都是同樣的),沒有一個文檔比另外一個文檔 更相關,因此這個時候使用範圍過濾器就很是合適了。
一般狀況下,要決定是使用過濾器仍是使用查詢,你就須要問本身是否須要相關度得分。若是相關度是不重要的,使用過濾器,不然使用查詢。若是你有SQL背 景,查詢和過濾器在概念上相似於SELECT WHERE語句, although more so for filters than queries
除了match_all, match, bool,filtered和range查詢,還有不少其它類型的查uxn/過濾器,咱們這裏不會涉及。因爲咱們已經對它們的工做原理有了基本的理解,將其應用到其它類型的查詢、過濾器上也不是件難事。
 

六、執行聚合

聚合提供了分組並統計數據的能力。理解聚合的最簡單的方式是將其粗略地等同爲SQL的GROUP BY和SQL聚合函數。

在Elasticsearch中,你能夠在一個響應中同時返回命中的數據和聚合結果。

你可使用簡單的API同時運行查詢和多個聚 合,並以一次返回,這避免了來回的網絡通訊,這是很是強大和高效的。

按照state分組,按照州名的計數倒序排序

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "size": 0,  
  4.     "aggs":{  
  5.         "group_by_state":{  
  6.             "terms":{  
  7.                 "field":"state"  
  8.             }  
  9.         }  
  10.     }  
  11. }  
在SQL中,上面的聚合在概念上相似於:
   SELECT COUNT(*) from bank GROUP BY state ORDER BY COUNT(*) DESC
 

注意咱們將size設置成0,這樣咱們就能夠只看到聚合結果了,而不會顯示命中的結果

這個例子計算了每一個州的帳戶的平均餘額(仍是按照帳戶數量倒序排序的前10個州)

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "size": 0,  
  4.     "aggs":{  
  5.         "group_by_state":{  
  6.             "terms":{  
  7.                 "field":"state"  
  8.             },  
  9.             "aggs":{  
  10.                 "average_balance": {  
  11.                     "avg": {  
  12.                         "field": "balance"  
  13.                     }  
  14.                 }  
  15.             }  
  16.         }  
  17.     }  
  18. }  
注意,咱們把average_balance聚合嵌套在了group_by_state聚合之中。這是全部聚合的一個經常使用模式。你能夠任意的聚合之中嵌套聚合,

這樣你就能夠從你的數據中抽取出想要的概述。

 

如今讓咱們按照平均餘額進行排序:

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "size": 0,  
  4.     "aggs":{  
  5.         "group_by_state":{  
  6.             "terms":{  
  7.                 "field":"state",  
  8.                 "order": {  
  9.                     "average_balance":"desc"  
  10.                 }  
  11.             },  
  12.             "aggs": {  
  13.                 "average_balance": {  
  14.                     "avg": {  
  15.                         "field": "balance"  
  16.                     }  
  17.                 }  
  18.             }  
  19.         }  
  20.     }  
  21. }  

使用年齡段(20-29,30-39,40-49)分組,而後在用性別分組,而後爲每個年齡段的每個性別計算平均帳戶餘額

 

[html]  view plain  copy
  1. POST /bank/_search?pretty  
  2. {  
  3.     "size": 0,  
  4.     "aggs": {  
  5.         "group_by_age": {  
  6.             "range": {  
  7.                 "field": "age",  
  8.                 "ranges":[  
  9.                     {  
  10.                         "from":20, "to":30  
  11.                     },  
  12.                     {  
  13.                         "from":30, "to":40  
  14.                     },  
  15.                     {  
  16.                         "from":40, "to":50  
  17.                     }  
  18.                 ]  
  19.             },  
  20.              "aggs": {  
  21.                 "group_by_gender": {  
  22.                     "terms": {  
  23.                         "field": "gender"  
  24.                     },  
  25.                     "aggs": {  
  26.                         "average_balance": {  
  27.                             "avg": {  
  28.                                 "field": "balance"  
  29.                             }  
  30.                         }  
  31.                     }  
  32.                 }  
  33.             }  
  34.         }  
  35.     }  
  36. }  

不少關於聚合的細節,咱們沒有涉及。若是你想作更進一步的實驗,

http://www.elasticsearch.org/guide/en /elasticsearch/reference/current/search-aggregations.html是一個很是好的起點。

相關文章
相關標籤/搜索