<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    狼愛上貍

    我胡漢三又回來了

    Elasticsearch基礎(chǔ)教程

    Elasticsearch基礎(chǔ)教程
        翻譯:潘飛(tinylambda@gmail.com)


    基礎(chǔ)概念



        Elasticsearch有幾個(gè)核心概念。從一開始理解這些概念會對整個(gè)學(xué)習(xí)過程有莫大的幫助。


        接近實(shí)時(shí)(NRT)
            Elasticsearch是一個(gè)接近實(shí)時(shí)的搜索平臺。這意味著,從索引一個(gè)文檔直到這個(gè)文檔能夠被搜索到有一個(gè)輕微的延遲(通常是1秒)。
           
        集群(cluster)
            一個(gè)集群就是由一個(gè)或多個(gè)節(jié)點(diǎn)組織在一起,它們共同持有你整個(gè)的數(shù)據(jù),并一起提供索引和搜索功能。一個(gè)集群由一個(gè)唯一的名字標(biāo)識,這個(gè)名字默認(rèn)就是 “elasticsearch”。這個(gè)名字是重要的,因?yàn)橐粋€(gè)節(jié)點(diǎn)只能通過指定某個(gè)集群的名字,來加入這個(gè)集群。在產(chǎn)品環(huán)境中顯式地設(shè)定這個(gè)名字是一個(gè)好 習(xí)慣,但是使用默認(rèn)值來進(jìn)行測試/開發(fā)也是不錯(cuò)的。
            
        節(jié)點(diǎn)(node)
            一個(gè)節(jié)點(diǎn)是你集群中的一個(gè)服務(wù)器,作為集群的一部分,它存儲你的數(shù)據(jù),參與集群的索引和搜索功能。和集群類似,一個(gè)節(jié)點(diǎn)也是由一個(gè)名字來標(biāo)識的,默認(rèn)情況 下,這個(gè)名字是一個(gè)隨機(jī)的漫威漫畫角色的名字,這個(gè)名字會在啟動的時(shí)候賦予節(jié)點(diǎn)。這個(gè)名字對于管理工作來說挺重要的,因?yàn)樵谶@個(gè)管理過程中,你會去確定網(wǎng) 絡(luò)中的哪些服務(wù)器對應(yīng)于Elasticsearch集群中的哪些節(jié)點(diǎn)。
            
            一個(gè)節(jié)點(diǎn)可以通過配置集群名稱的方式來加入一個(gè)指定的集群。默認(rèn)情況下,每個(gè)節(jié)點(diǎn)都會被安排加入到一個(gè)叫做“elasticsearch”的集群中,這意 味著,如果你在你的網(wǎng)絡(luò)中啟動了若干個(gè)節(jié)點(diǎn),并假定它們能夠相互發(fā)現(xiàn)彼此,它們將會自動地形成并加入到一個(gè)叫做“elasticsearch”的集群中。
            
            在一個(gè)集群里,只要你想,可以擁有任意多個(gè)節(jié)點(diǎn)。而且,如果當(dāng)前你的網(wǎng)絡(luò)中沒有運(yùn)行任何Elasticsearch節(jié)點(diǎn),這時(shí)啟動一個(gè)節(jié)點(diǎn),會默認(rèn)創(chuàng)建并加入一個(gè)叫做“elasticsearch”的集群。
            
        索引(index)
            
            一個(gè)索引就是一個(gè)擁有幾分相似特征的文檔的集合。比如說,你可以有一個(gè)客戶數(shù)據(jù)的索引,另一個(gè)產(chǎn)品目錄的索引,還有一個(gè)訂單數(shù)據(jù)的索引。一個(gè)索引由一個(gè)名 字來標(biāo)識(必須全部是小寫字母的),并且當(dāng)我們要對對應(yīng)于這個(gè)索引中的文檔進(jìn)行索引、搜索、更新和刪除的時(shí)候,都要使用到這個(gè)名字。
            
            在一個(gè)集群中,如果你想,可以定義任意多的索引。
            
        類型(type)


            在一個(gè)索引中,你可以定義一種或多種類型。一個(gè)類型是你的索引的一個(gè)邏輯上的分類/分區(qū),其語義完全由你來定。通常,會為具有一組共同字段的文檔定義一個(gè) 類型。比如說,我們假設(shè)你運(yùn)營一個(gè)博客平臺并且將你所有的數(shù)據(jù)存儲到一個(gè)索引中。在這個(gè)索引中,你可以為用戶數(shù)據(jù)定義一個(gè)類型,為博客數(shù)據(jù)定義另一個(gè)類 型,當(dāng)然,也可以為評論數(shù)據(jù)定義另一個(gè)類型。
            
        文檔(document)
            
            一個(gè)文檔是一個(gè)可被索引的基礎(chǔ)信息單元。比如,你可以擁有某一個(gè)客戶的文檔,某一個(gè)產(chǎn)品的一個(gè)文檔,當(dāng)然,也可以擁有某個(gè)訂單的一個(gè)文檔。文檔以 JSON(Javascript Object Notation)格式來表示,而JSON是一個(gè)到處存在的互聯(lián)網(wǎng)數(shù)據(jù)交互格式。
            
            在一個(gè)index/type里面,只要你想,你可以存儲任意多的文檔。注意,盡管一個(gè)文檔,物理上存在于一個(gè)索引之中,文檔必須被索引/賦予一個(gè)索引的type。
            
        分片和復(fù)制(shards & replicas)
            
            一個(gè)索引可以存儲超出單個(gè)結(jié)點(diǎn)硬件限制的大量數(shù)據(jù)。比如,一個(gè)具有10億文檔的索引占據(jù)1TB的磁盤空間,而任一節(jié)點(diǎn)都沒有這樣大的磁盤空間;或者單個(gè)節(jié)點(diǎn)處理搜索請求,響應(yīng)太慢。
            
            為了解決這個(gè)問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片。當(dāng)你創(chuàng)建一個(gè)索引的時(shí)候,你可以指定你想要的分片的數(shù)量。每個(gè)分片本身也是一個(gè)功能完善并且獨(dú)立的“索引”,這個(gè)“索引”可以被放置到集群中的任何節(jié)點(diǎn)上。
            
            分片之所以重要,主要有兩方面的原因:
            
                - 允許你水平分割/擴(kuò)展你的內(nèi)容容量
                - 允許你在分片(潛在地,位于多個(gè)節(jié)點(diǎn)上)之上進(jìn)行分布式的、并行的操作,進(jìn)而提高性能/吞吐量
            
            至于一個(gè)分片怎樣分布,它的文檔怎樣聚合回搜索請求,是完全由Elasticsearch管理的,對于作為用戶的你來說,這些都是透明的。
            
            在一個(gè)網(wǎng)絡(luò)/云的環(huán)境里,失敗隨時(shí)都可能發(fā)生,在某個(gè)分片/節(jié)點(diǎn)不知怎么的就處于離線狀態(tài),或者由于任何原因消失了,這種情況下,有一個(gè)故障轉(zhuǎn)移機(jī)制是非 常有用并且是強(qiáng)烈推薦的。為此目的,Elasticsearch允許你創(chuàng)建分片的一份或多份拷貝,這些拷貝叫做復(fù)制分片,或者直接叫復(fù)制。
            
            復(fù)制之所以重要,有兩個(gè)主要原因:
                - 在分片/節(jié)點(diǎn)失敗的情況下,提供了高可用性。因?yàn)檫@個(gè)原因,注意到復(fù)制分片從不與原/主要(original/primary)分片置于同一節(jié)點(diǎn)上是非常重要的。
                - 擴(kuò)展你的搜索量/吞吐量,因?yàn)樗阉骺梢栽谒械膹?fù)制上并行運(yùn)行
                
            總之,每個(gè)索引可以被分成多個(gè)分片。一個(gè)索引也可以被復(fù)制0次(意思是沒有復(fù)制)或多次。一旦復(fù)制了,每個(gè)索引就有了主分片(作為復(fù)制源的原來的分片)和 復(fù)制分片(主分片的拷貝)之別。分片和復(fù)制的數(shù)量可以在索引創(chuàng)建的時(shí)候指定。在索引創(chuàng)建之后,你可以在任何時(shí)候動態(tài)地改變復(fù)制的數(shù)量,但是你事后不能改變 分片的數(shù)量。
            
            默認(rèn)情況下,Elasticsearch中的每個(gè)索引被分片5個(gè)主分片和1個(gè)復(fù)制,這意味著,如果你的集群中至少有兩個(gè)節(jié)點(diǎn),你的索引將會有5個(gè)主分片和另外5個(gè)復(fù)制分片(1個(gè)完全拷貝),這樣的話每個(gè)索引總共就有10個(gè)分片。
            
            這些問題搞清楚之后,我們就要進(jìn)入好玩的部分了...


    安裝


        Elasticsearch依賴Java 7。在本文寫作的時(shí)候,推薦使用Oracle JDK 1.7.0_55版本。Java的安裝,在各個(gè)平臺上都有差異,所以我們不想在這里深入太多細(xì)節(jié)。我只想說,在你安裝Elasticsearch之前,你 可以通過以下命令來檢查你的Java版本(如果有需要,安裝或者升級):


            java -version
            echo $JAVA_HOME


        一旦我們將Java安裝完成,我們就可以下載并安裝Elasticsearch了。其二進(jìn)制文件可以從 www.elasticsearch.org/download這里下載,你也可以從這里下載以前發(fā)布的版本。對于每個(gè)版本,你可以在zip、tar、 DEB、RPM類型的包中選擇下載。簡單起見,我們使用tar包。


        我們像下面一樣下載Elasticsearch 1.1.1 tar包(Windows用戶應(yīng)該下載zip包):
            
            curl -L -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.1.tar.gz


        然后,如下將其解壓(Windows下需要unzip響應(yīng)的zip包):


            tar -xzvf elasticsearch-1.1.1.tar.gz
            
        這將在你的當(dāng)前目錄下創(chuàng)建很多文件和目錄。然后,我們進(jìn)入到bin目錄下:
            
            cd elasticsearch-1.1.1/bin


        至此,我們已經(jīng)準(zhǔn)備好開啟我們的節(jié)點(diǎn)和單節(jié)點(diǎn)集群(Windows用戶應(yīng)該運(yùn)行elasticsearch.bat文件):
            
            ./elasticsearch
            
        如果一切順利,你將看到大量的如下信息:


            ./elasticsearch
            [2014-03-13 13:42:17,218][INFO ][node           ] [New Goblin] version[1.1.1], pid[2085], build[5c03844/2014-02-25T15:52:53Z]
            [2014-03-13 13:42:17,219][INFO ][node           ] [New Goblin] initializing ...
            [2014-03-13 13:42:17,223][INFO ][plugins        ] [New Goblin] loaded [], sites []
            [2014-03-13 13:42:19,831][INFO ][node           ] [New Goblin] initialized
            [2014-03-13 13:42:19,832][INFO ][node           ] [New Goblin] starting ...
            [2014-03-13 13:42:19,958][INFO ][transport      ] [New Goblin] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.8.112:9300]}
            [2014-03-13 13:42:23,030][INFO ][cluster.service] [New Goblin] new_master [New Goblin][rWMtGj3dQouz2r6ZFL9v4g][mwubuntu1][inet[/192.168.8.112:9300]], reason: zen-disco-join (elected_as_master)
            [2014-03-13 13:42:23,100][INFO ][discovery      ] [New Goblin] elasticsearch/rWMtGj3dQouz2r6ZFL9v4g
            [2014-03-13 13:42:23,125][INFO ][http           ] [New Goblin] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/192.168.8.112:9200]}
            [2014-03-13 13:42:23,629][INFO ][gateway        ] [New Goblin] recovered [1] indices into cluster_state
            [2014-03-13 13:42:23,630][INFO ][node           ] [New Goblin] started
            
        不去涉及太多細(xì)節(jié),我們可以看到,一叫做“New Goblin”(你會見到一個(gè)不同的漫威漫畫角色)的節(jié)點(diǎn)啟動并且將自己選做單結(jié)點(diǎn)集群的master。現(xiàn)在不用關(guān)心master是什么東西。這里重要的就是,我們在一個(gè)集群中開啟了一個(gè)節(jié)點(diǎn)。


        正如先前提到的,我們可以覆蓋集群或者節(jié)點(diǎn)的名字。我們可以在啟動Elasticsearch的時(shí)候通過命令行來指定,如下:
            
            ./elasticsearch --cluster.name my_cluster_name --node.name my_node_name
            
        也要注意一下有http標(biāo)記的那一行,它提供了有關(guān)HTTP地址(192.168.8.112)和端口(9200)的信息,通過這個(gè)地址和端口我們就可以 訪問我們的節(jié)點(diǎn)了。默認(rèn)情況下,Elasticsearch使用9200來提供對其REST API的訪問。如果有必要,這個(gè)端口是可以配置的。




    探索你的集群


        rest接口
            
            現(xiàn)在我們已經(jīng)有一個(gè)正常運(yùn)行的節(jié)點(diǎn)(和集群)了,下一步就是要去理解怎樣與其通信了。幸運(yùn)的是,Elasticsearch提供了非常全面和強(qiáng)大的 REST API,利用這個(gè)REST API你可以同你的集群交互。下面是利用這個(gè)API,可以做的幾件事情:
            
                - 檢查你的集群、節(jié)點(diǎn)和索引的健康狀態(tài)、和各種統(tǒng)計(jì)信息
                - 管理你的集群、節(jié)點(diǎn)、索引數(shù)據(jù)和元數(shù)據(jù)
                - 對你的索引進(jìn)行CRUD(創(chuàng)建、讀取、更新和刪除)和搜索操作
                - 執(zhí)行高級的查詢操作,像是分頁、排序、過濾、腳本編寫(scripting)、小平面刻畫(faceting)、聚合(aggregations)和許多其它操作
               
               
        集群健康
        
            讓我們以基本的健康檢查作為開始,我們可以利用它來查看我們集群的狀態(tài)。此過程中,我們使用curl,當(dāng)然,你也可以使用任何可以創(chuàng)建HTTP/REST 調(diào)用的工具。我們假設(shè)我們還在我們啟動Elasticsearch的節(jié)點(diǎn)上并打開另外一個(gè)shell窗口。
            
            要檢查集群健康,我們將使用_cat API。需要事先記住的是,我們的節(jié)點(diǎn)HTTP的端口是9200:
            
                curl 'localhost:9200/_cat/health?v'
            
            相應(yīng)的響應(yīng)是:
            
                epoch      timestamp cluster       status node.total node.data shards pri relo init unassign
                1394735289 14:28:09  elasticsearch green           1         1      0   0    0    0        0
                
            可以看到,我們集群的名字是“elasticsearch”,正常運(yùn)行,并且狀態(tài)是綠色。
            
            當(dāng)我們詢問集群狀態(tài)的時(shí)候,我們要么得到綠色、黃色或紅色。綠色代表一切正常(集群功能齊全),黃色意味著所有的數(shù)據(jù)都是可用的,但是某些復(fù)制沒有被分配 (集群功能齊全),紅色則代表因?yàn)槟承┰颍承?shù)據(jù)不可用。注意,即使是集群狀態(tài)是紅色的,集群仍然是部分可用的(它仍然會利用可用的分片來響應(yīng)搜索請 求),但是可能你需要盡快修復(fù)它,因?yàn)槟阌衼G失的數(shù)據(jù)。
            
            也是從上面的響應(yīng)中,我們可以看到,一共有一個(gè)節(jié)點(diǎn),由于里面沒有數(shù)據(jù),我們有0個(gè)分片。注意,由于我們使用默認(rèn)的集群名字 (elasticsearch),并且由于Elasticsearch默認(rèn)使用網(wǎng)絡(luò)多播(multicast)發(fā)現(xiàn)其它節(jié)點(diǎn),如果你在你的網(wǎng)絡(luò)中啟動了多 個(gè)節(jié)點(diǎn),你就已經(jīng)把她們加入到一個(gè)集群中了。在這種情形下,你可能在上面的響應(yīng)中看到多個(gè)節(jié)點(diǎn)。
            
            我們也可以獲得節(jié)集群中的節(jié)點(diǎn)列表:
                
                curl 'localhost:9200/_cat/nodes?v'
                
            對應(yīng)的響應(yīng)是:
            
                curl 'localhost:9200/_cat/nodes?v'
                host         ip        heap.percent ram.percent load node.role master name
                mwubuntu1    127.0.1.1            8           4 0.00 d         *      New Goblin
            
            這兒,我們可以看到我們叫做“New Goblin”的節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)是我們集群中的唯一節(jié)點(diǎn)。
            
            
        列出所有的索引
            讓我們看一下我們的索引:
                
                curl 'localhost:9200/_cat/indices?v'
                
            響應(yīng)是:
                
                curl 'localhost:9200/_cat/indices?v'
                health index pri rep docs.count docs.deleted store.size pri.store.size
                
            這個(gè)結(jié)果意味著,在我們的集群中,我們沒有任何索引。
            
            
        創(chuàng)建一個(gè)索引
        
            現(xiàn)在讓我們創(chuàng)建一個(gè)叫做“customer”的索引,然后再列出所有的索引:
            
                curl -XPUT 'localhost:9200/customer?pretty'
                curl 'localhost:9200/_cat/indices?v'
            
            第一個(gè)命令使用PUT創(chuàng)建了一個(gè)叫做“customer”的索引。我們簡單地將pretty附加到調(diào)用的尾部,使其以美觀的形式打印出JSON響應(yīng)(如果有的話)。
            響應(yīng)如下:
            
                curl -XPUT 'localhost:9200/customer?pretty'
                {
                  "acknowledged" : true
                }


                curl 'localhost:9200/_cat/indices?v'
                health index    pri rep docs.count docs.deleted store.size pri.store.size
                yellow customer   5   1          0            0       495b           495b
                
            第二個(gè)命令的結(jié)果告知我們,我們現(xiàn)在有一個(gè)叫做customer的索引,并且它有5個(gè)主分片和1份復(fù)制(都是默認(rèn)值),其中包含0個(gè)文檔。
            
            你可能也注意到了這個(gè)customer索引有一個(gè)黃色健康標(biāo)簽。回顧我們之前的討論,黃色意味著某些復(fù)制沒有(或者還未)被分配。這個(gè)索引之所以這樣,是 因?yàn)镋lasticsearch默認(rèn)為這個(gè)索引創(chuàng)建一份復(fù)制。由于現(xiàn)在我們只有一個(gè)節(jié)點(diǎn)在運(yùn)行,那一份復(fù)制就分配不了了(為了高可用),直到當(dāng)另外一個(gè)節(jié) 點(diǎn)加入到這個(gè)集群后,才能分配。一旦那份復(fù)制在第二個(gè)節(jié)點(diǎn)上被復(fù)制,這個(gè)節(jié)點(diǎn)的健康狀態(tài)就會變成綠色。
            


    索引并查詢一個(gè)文檔
        現(xiàn)在讓我們放一些東西到customer索引中。首先要知道的是,為了索引一個(gè)文檔,我們必須告訴Elasticsearch這個(gè)文檔要到這個(gè)索引的哪個(gè)類型(type)下。
        
        讓我們將一個(gè)簡單的客戶文檔索引到customer索引、“external”類型中,這個(gè)文檔的ID是1,操作如下:
            
            curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
            {
              "name": "John Doe"
            }'
            
        響應(yīng)如下:
        
            curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
            {
              "name": "John Doe"
            }'
            {
              "_index" : "customer",
              "_type" : "external",
              "_id" : "1",
              "_version" : 1,
              "created" : true
            }
            
        從上面的響應(yīng)中,我們可以看到,一個(gè)新的客戶文檔在customer索引和external類型中被成功創(chuàng)建。文檔也有一個(gè)內(nèi)部id 1, 這個(gè)id是我們在索引的時(shí)候指定的。
        
        有一個(gè)關(guān)鍵點(diǎn)需要注意,Elasticsearch在你想將文檔索引到某個(gè)索引的時(shí)候,并不強(qiáng)制要求這個(gè)索引被顯式地創(chuàng)建。在前面這個(gè)例子中,如果customer索引不存在,Elasticsearch將會自動地創(chuàng)建這個(gè)索引。
        
        現(xiàn)在,讓我們把剛剛索引的文檔取出來:
        
            curl -XGET 'localhost:9200/customer/external/1?pretty'
            
        響應(yīng)如下:
        
            curl -XGET 'localhost:9200/customer/external/1?pretty'
            {
              "_index" : "customer",
              "_type" : "external",
              "_id" : "1",
              "_version" : 1,
              "found" : true, "_source" : { "name": "John Doe" }
            }
            
        除了一個(gè)叫做found的字段來指明我們找到了一個(gè)ID為1的文檔,和另外一個(gè)字段——_source——返回我們前一步中索引的完整JSON文檔之外,其它的都沒有什么特別之處。
        
        
    刪除一個(gè)文檔
        
        現(xiàn)在讓我們刪除我們剛剛創(chuàng)建的索引,并再次列出所有的索引:
        
            curl -XDELETE 'localhost:9200/customer?pretty'
            curl 'localhost:9200/_cat/indices?v'
            
        響應(yīng)如下:
        
            curl -XDELETE 'localhost:9200/customer?pretty'
            {
              "acknowledged" : true
            }
            curl 'localhost:9200/_cat/indices?v'
            health index pri rep docs.count docs.deleted store.size pri.store.size
            
        這表明我們成功地刪除了這個(gè)索引,現(xiàn)在我們回到了集群中空無所有的狀態(tài)。
        
        在更進(jìn)一步之前,我們再細(xì)看一下一些我們學(xué)過的API命令:
            
            curl -XPUT 'localhost:9200/customer'
            curl -XPUT 'localhost:9200/customer/external/1' -d '
            {
              "name": "John Doe"
            }'
            curl 'localhost:9200/customer/external/1'
            curl -XDELETE 'localhost:9200/customer'
            
        如果我們仔細(xì)研究以上的命令,我們可以發(fā)現(xiàn)訪問Elasticsearch中數(shù)據(jù)的一個(gè)模式。這個(gè)模式可以被總結(jié)為:
        
            curl -<REST Verb> <Node>:<Port>/<Index>/<Type><ID>
            
        這個(gè)REST訪問模式普遍適用于所有的API命令,如果你能記住它,你就會為掌握Elasticsearch開一個(gè)好頭。
        


    修改你的數(shù)據(jù)


        Elasticsearch提供了近乎實(shí)時(shí)的數(shù)據(jù)操作和搜索功能。默認(rèn)情況下,從你索引/更新/刪除你的數(shù)據(jù)動作開始到它出現(xiàn)在你的搜索結(jié)果中,大概會有1秒鐘的延遲。這和其它類似SQL的平臺不同,數(shù)據(jù)在一個(gè)事務(wù)完成之后就會立即可用。
        
        索引/替換文檔
            
            我們先前看到,怎樣索引一個(gè)文檔。現(xiàn)在我們再次調(diào)用那個(gè)命令:
                curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
                {
                  "name": "John Doe"
                }'
                
            再次,以上的命令將會把這個(gè)文檔索引到customer索引、external類型中,其ID是1。如果我們對一個(gè)不同(或相同)的文檔應(yīng)用以上的命令,Elasticsearch將會用一個(gè)新的文檔來替換(重新索引)當(dāng)前ID為1的那個(gè)文檔。
            
                curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
                {
                  "name": "Jane Doe"
                }'
                
            以上的命令將ID為1的文檔的name字段的值從“John Doe”改成了“Jane Doe”。如果我們使用一個(gè)不同的ID,一個(gè)新的文檔將會被索引,當(dāng)前已經(jīng)在索引中的文檔不會受到影響。
            
                curl -XPUT 'localhost:9200/customer/external/2?pretty' -d '
                {
                  "name": "Jane Doe"
                }'
                
            以上的命令,將會索引一個(gè)ID為2的新文檔。
            
            在索引的時(shí)候,ID部分是可選的。如果不指定,Elasticsearch將產(chǎn)生一個(gè)隨機(jī)的ID來索引這個(gè)文檔。Elasticsearch生成的ID會作為索引API調(diào)用的一部分被返回。
            
            以下的例子展示了怎樣在沒有指定ID的情況下來索引一個(gè)文檔:
            
                curl -XPOST 'localhost:9200/customer/external?pretty' -d '
                {
                  "name": "Jane Doe"
                }'
                
            注意,在上面的情形中,由于我們沒有指定一個(gè)ID,我們使用的是POST而不是PUT。




    更新文檔
        
        除了可以索引、替換文檔之外,我們也可以更新一個(gè)文檔。但要注意,Elasticsearch底層并不支持原地更新。在我們想要做一次更新的時(shí)候,Elasticsearch先刪除舊文檔,然后在索引一個(gè)更新過的新文檔。
        
        下面的例子展示了怎樣將我們ID為1的文檔的name字段改成“Jane Doe”:
        
            curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
            {
              "doc": { "name": "Jane Doe" }
            }'
            
        下面的例子展示了怎樣將我們ID為1的文檔的name字段改成“Jane Doe”的同時(shí),給它加上age字段:
        
            curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
            {
              "doc": { "name": "Jane Doe", "age": 20 }
            }'
            
        更新也可以通過使用簡單的腳本來進(jìn)行。這個(gè)例子使用一個(gè)腳本將age加5:
        
            curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
            {
              "script" : "ctx._source.age += 5"
            }'
            
        在上面的例子中,ctx._source指向當(dāng)前要被更新的文檔。
        
        注意,在寫作本文時(shí),更新操作只能一次應(yīng)用在一個(gè)文檔上。將來,Elasticsearch將提供同時(shí)更新符合指定查詢條件的多個(gè)文檔的功能(類似于SQL的UPDATE-WHERE語句)。
        


    刪除文檔
        
        刪除文檔是相當(dāng)直觀的。以下的例子展示了我們怎樣刪除ID為2的文檔:
        
            curl -XDELETE 'localhost:9200/customer/external/2?pretty'
        
        我們也能夠一次刪除符合某個(gè)查詢條件的多個(gè)文檔。以下的例子展示了如何刪除名字中包含“John”的所有的客戶:
        
            curl -XDELETE 'localhost:9200/customer/external/_query?pretty' -d '
            {
              "query": { "match": { "name": "John" } }
            }'
            
        注意,以上的URI變成了/_query,以此來表明這是一個(gè)“查詢刪除”API,其中刪除查詢標(biāo)準(zhǔn)放在請求體中,但是我們?nèi)匀皇褂肈ELETE。現(xiàn)在先不要擔(dān)心查詢語法,我們將會在本教程后面的部分中涉及。
        


    批處理:
        
        除了能夠?qū)蝹€(gè)的文檔進(jìn)行索引、更新和刪除之外,Elasticsearch也提供了以上操作的批量處理功能,這是通過使用_bulk API實(shí)現(xiàn)的。這個(gè)功能之所以重要,在于它提供了非常高效的機(jī)制來盡可能快的完成多個(gè)操作,與此同時(shí)使用盡可能少的網(wǎng)絡(luò)往返。
        
        作為一個(gè)快速的例子,以下調(diào)用在一次bulk操作中索引了兩個(gè)文檔(ID 1 - John Doe and ID 2 - Jane Doe):
            
            curl -XPOST 'localhost:9200/customer/external/_bulk?pretty' -d '
            {"index":{"_id":"1"}}
            {"name": "John Doe" }
            {"index":{"_id":"2"}}
            {"name": "Jane Doe" }
            '
            
        以下例子在一個(gè)bulk操作中,首先更新第一個(gè)文檔(ID為1),然后刪除第二個(gè)文檔(ID為2):
        
            curl -XPOST 'localhost:9200/customer/external/_bulk?pretty' -d '
            {"update":{"_id":"1"}}
            {"doc": { "name": "John Doe becomes Jane Doe" } }
            {"delete":{"_id":"2"}}
            '
            
        注意上面的delete動作,由于刪除動作只需要被刪除文檔的ID,所以并沒有對應(yīng)的源文檔。
        
        bulk API按順序執(zhí)行這些動作。如果其中一個(gè)動作因?yàn)槟承┰蚴×耍瑢^續(xù)處理它后面的動作。當(dāng)bulk API返回時(shí),它將提供每個(gè)動作的狀態(tài)(按照同樣的順序),所以你能夠看到某個(gè)動作成功與否。




    探索你的數(shù)據(jù)


        樣本數(shù)據(jù)集
            現(xiàn)在我們對于基本的東西已經(jīng)有了一些感覺,現(xiàn)在讓我們嘗試使用一些更加貼近現(xiàn)實(shí)的數(shù)據(jù)集。我已經(jīng)準(zhǔn)備了一些假想的客戶的銀行賬戶信息的JSON文檔的樣本。文檔具有以下的模式(schema):
            
                {
                    "account_number": 0,
                    "balance": 16623,
                    "firstname": "Bradshaw",
                    "lastname": "Mckenzie",
                    "age": 29,
                    "gender": "F",
                    "address": "244 Columbus Place",
                    "employer": "Euron",
                    "email": "bradshawmckenzie@euron.com",
                    "city": "Hobucken",
                    "state": "CO"
                }
                
            我是在http://www.json-generator.com/上生成這些數(shù)據(jù)的。
            
        載入樣本數(shù)據(jù)
        
            你可以從https://github.com/bly2k/files/blob/master/accounts.zip?raw=true下載這個(gè)樣本數(shù)據(jù)集。將其解壓到當(dāng)前目錄下,如下,將其加載到我們的集群里:
            
                curl -XPOST 'localhost:9200/bank/account/_bulk?pretty' --data-binary @accounts.json
                curl 'localhost:9200/_cat/indices?v'
            
            響應(yīng)是:
                curl 'localhost:9200/_cat/indices?v'
                health index pri rep docs.count docs.deleted store.size pri.store.size
                yellow bank    5   1       1000            0    424.4kb        424.4kb
                
            這意味著我們成功批量索引了1000個(gè)文檔到銀行索引中(account類型)。
            
        
        搜索API
        
            現(xiàn)在,讓我們以一些簡單的搜索來開始。有兩種基本的方式來運(yùn)行搜索:一種是在REST請求的URI中發(fā)送搜索參數(shù),另一種是將搜索參數(shù)發(fā)送到REST請求 體中。請求體方法的表達(dá)能力更好,并且你可以使用更加可讀的JSON格式來定義搜索。我們將嘗試使用一次請求URI作為例子,但是教程的后面部分,我們將 僅僅使用請求體方法。
            
            搜索的REST API可以通過_search端點(diǎn)來訪問。下面這個(gè)例子返回bank索引中的所有的文檔:
            
                curl 'localhost:9200/bank/_search?q=*&pretty'
                
            我們仔細(xì)研究一下這個(gè)查詢調(diào)用。我們在bank索引中搜索(_search端點(diǎn)),并且q=*參數(shù)指示Elasticsearch去匹配這個(gè)索引中所有的文檔。pretty參數(shù),和以前一樣,僅僅是告訴Elasticsearch返回美觀的JSON結(jié)果。
            
            以下是響應(yīng)(部分列出):
                
                curl 'localhost:9200/bank/_search?q=*&pretty'
                {
                  "took" : 63,
                  "timed_out" : false,
                  "_shards" : {
                    "total" : 5,
                    "successful" : 5,
                    "failed" : 0
                  },
                  "hits" : {
                    "total" : 1000,
                    "max_score" : 1.0,
                    "hits" : [ {
                      "_index" : "bank",
                      "_type" : "account",
                      "_id" : "1",
                      "_score" : 1.0, "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
                    }, {
                      "_index" : "bank",
                      "_type" : "account",
                      "_id" : "6",
                      "_score" : 1.0, "_source" : {"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
                    }, {
                      "_index" : "bank",
                      "_type" : "account",
                      
            對于這個(gè)響應(yīng),我們看到了以下的部分:
              - took —— Elasticsearch執(zhí)行這個(gè)搜索的耗時(shí),以毫秒為單位
              - timed_out —— 指明這個(gè)搜索是否超時(shí)
              - _shards —— 指出多少個(gè)分片被搜索了,同時(shí)也指出了成功/失敗的被搜索的shards的數(shù)量
              - hits —— 搜索結(jié)果
              - hits.total —— 能夠匹配我們查詢標(biāo)準(zhǔn)的文檔的總數(shù)目
              - hits.hits —— 真正的搜索結(jié)果數(shù)據(jù)(默認(rèn)只顯示前10個(gè)文檔)
              - _score和max_score —— 現(xiàn)在先忽略這些字段
                
            使用請求體方法的等價(jià)搜索是:
            
                curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
                {
                  "query": { "match_all": {} }
                }'
                
            這里的不同之處在于,并不是向URI中傳遞q=*,取而代之的是,我們在_search API的請求體中POST了一個(gè)JSON格式請求體。我們將在下一部分中討論這個(gè)JSON查詢。
            
            響應(yīng)是:
                
                curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
                {
                  "query": { "match_all": {} }
                }'
                {
                  "took" : 26,
                  "timed_out" : false,
                  "_shards" : {
                    "total" : 5,
                    "successful" : 5,
                    "failed" : 0
                  },
                  "hits" : {
                    "total" : 1000,
                    "max_score" : 1.0,
                    "hits" : [ {
                      "_index" : "bank",
                      "_type" : "account",
                      "_id" : "1",
                      "_score" : 1.0, "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
                    }, {
                      "_index" : "bank",
                      "_type" : "account",
                      "_id" : "6",
                      "_score" : 1.0, "_source" : {"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
                    }, {
                      "_index" : "bank",
                      "_type" : "account",
                      "_id" : "13",
            
            有一點(diǎn)需要重點(diǎn)理解一下,一旦你取回了你的搜索結(jié)果,Elasticsearch就完成了使命,它不會維護(hù)任何服務(wù)器端的資源或者在你的結(jié)果中打開游標(biāo)。 這是和其它類似SQL的平臺的一個(gè)鮮明的對比, 在那些平臺上,你可以在前面先獲取你查詢結(jié)果的一部分,然后如果你想獲取結(jié)果的剩余部分,你必須繼續(xù)返回服務(wù)端去取,這個(gè)過程使用一種有狀態(tài)的服務(wù)器端游 標(biāo)技術(shù)。
            
    介紹查詢語言


        Elasticsearch提供一種JSON風(fēng)格的特定領(lǐng)域語言,利用它你可以執(zhí)行查詢。這杯稱為查詢DSL。這個(gè)查詢語言相當(dāng)全面,第一眼看上去可能有些咄咄逼人,但是最好的學(xué)習(xí)方法就是以幾個(gè)基礎(chǔ)的例子來開始。
        
        回到我們上一個(gè)例子,我們執(zhí)行了這個(gè)查詢:
        
            {
              "query": { "match_all": {} }
            }
            
        分解以上的這個(gè)查詢,其中的query部分告訴我查詢的定義,match_all部分就是我們想要運(yùn)行的查詢的類型。match_all查詢,就是簡單地查詢一個(gè)指定索引下的所有的文檔。
        
        除了這個(gè)query參數(shù)之外,我們也可以通過傳遞其它的參數(shù)來影響搜索結(jié)果。比如,下面做了一次match_all并只返回第一個(gè)文檔:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": { "match_all": {} },
              "size": 1
            }'
        
        注意,如果沒有指定size的值,那么它默認(rèn)就是10。
        
        下面的例子,做了一次match_all并且返回第11到第20個(gè)文檔:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": { "match_all": {} },
              "from": 10,
              "size": 10
            }'
            
        其中的from參數(shù)(0-based)從哪個(gè)文檔開始,size參數(shù)指明從from參數(shù)開始,要返回多少個(gè)文檔。這個(gè)特性對于搜索結(jié)果分頁來說非常有幫助。注意,如果不指定from的值,它默認(rèn)就是0。
        
        下面這個(gè)例子做了一次match_all并且以賬戶余額降序排序,最后返前十個(gè)文檔:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": { "match_all": {} },
              "sort": { "balance": { "order": "desc" } }
            }'
            
            
    執(zhí)行搜索


        現(xiàn)在我們已經(jīng)知道了幾個(gè)基本的參數(shù),讓我們進(jìn)一步發(fā)掘查詢語言吧。首先我們看一下返回文檔的字段。默認(rèn)情況下,是返回完整的JSON文檔的。這可以通過 source來引用(搜索hits中的_sourcei字段)。如果我們不想返回完整的源文檔,我們可以指定返回的幾個(gè)字段。
        
        下面這個(gè)例子說明了怎樣返回兩個(gè)字段account_number和balance(當(dāng)然,這兩個(gè)字段都是指_source中的字段),以下是具體的搜索:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": { "match_all": {} },
              "_source": ["account_number", "balance"]
            }'
            
        注意到上面的例子僅僅是簡化了_source字段。它仍將會返回一個(gè)叫做_source的字段,但是僅僅包含account_number和balance來年改革字段。
        
        如果你有SQL背景,上述查詢在概念上有些像SQL的SELECT FROM。
        
        現(xiàn)在讓我們進(jìn)入到查詢部分。之前,我們看到了match_all查詢是怎樣匹配到所有的文檔的。現(xiàn)在我們介紹一種新的查詢,叫做match查詢,這可以看成是一個(gè)簡單的字段搜索查詢(比如對應(yīng)于某個(gè)或某些特定字段的搜索)。
        
        下面這個(gè)例子返回賬戶編號為20的文檔:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": { "match": { "account_number": 20 } }
            }'
            
        下面這個(gè)例子返回地址中包含“mill”的所有賬戶:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": { "match": { "address": "mill" } }
            }'
            
        下面這個(gè)例子返回地址中包含“mill”或者包含“lane”的賬戶:
        
           curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": { "match": { "address": "mill lane" } }
            }' 
            
        下面這個(gè)例子是match的變體(match_phrase),它會去匹配短語“mill lane”:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": { "match_phrase": { "address": "mill lane" } }
            }'
            
        現(xiàn)在,讓我們介紹一下布爾查詢。布爾查詢允許我們利用布爾邏輯將較小的查詢組合成較大的查詢。
        
        現(xiàn)在這個(gè)例子組合了兩個(gè)match查詢,這個(gè)組合查詢返回包含“mill”和“lane”的所有的賬戶:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": {
                "bool": {
                  "must": [
                    { "match": { "address": "mill" } },
                    { "match": { "address": "lane" } }
                  ]
                }
              }
            }'
            
        在上面的例子中,bool must語句指明了,對于一個(gè)文檔,所有的查詢都必須為真,這個(gè)文檔才能夠匹配成功。
        
        相反的,下面的例子組合了兩個(gè)match查詢,它返回的是地址中包含“mill”或者“lane”的所有的賬戶:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": {
                "bool": {
                  "should": [
                    { "match": { "address": "mill" } },
                    { "match": { "address": "lane" } }
                  ]
                }
              }
            }'
            
        在上面的例子中,bool should語句指明,對于一個(gè)文檔,查詢列表中,只要有一個(gè)查詢匹配,那么這個(gè)文檔就被看成是匹配的。
        
        現(xiàn)在這個(gè)例子組合了兩個(gè)查詢,它返回地址中既不包含“mill”,同時(shí)也不包含“lane”的所有的賬戶信息:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": {
                "bool": {
                  "must_not": [
                    { "match": { "address": "mill" } },
                    { "match": { "address": "lane" } }
                  ]
                }
              }
            }'
            
        在上面的例子中, bool must_not語句指明,對于一個(gè)文檔,查詢列表中的的所有查詢都必須都不為真,這個(gè)文檔才被認(rèn)為是匹配的。
        
        我們可以在一個(gè)bool查詢里一起使用must、should、must_not。此外,我們可以將bool查詢放到這樣的bool語句中來模擬復(fù)雜的、多等級的布爾邏輯。
        
        下面這個(gè)例子返回40歲以上并且不生活在ID(daho)的人的賬戶:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": {
                "bool": {
                  "must": [
                    { "match": { "age": "40" } }
                  ],
                  "must_not": [
                    { "match": { "state": "ID" } }
                  ]
                }
              }
            }'
            
        
    執(zhí)行過濾器
        
        在先前的章節(jié)中,我們跳過了文檔得分的細(xì)節(jié)(搜索結(jié)果中的_score字段)。這個(gè)得分是與我們指定的搜索查詢匹配程度的一個(gè)相對度量。得分越高,文檔越相關(guān),得分越低文檔的相關(guān)度越低。
        
        Elasticsearch中的所有的查詢都會觸發(fā)相關(guān)度得分的計(jì)算。對于那些我們不需要相關(guān)度得分的場景下,Elasticsearch以過濾器的形式 提供了另一種查詢功能。過濾器在概念上類似于查詢,但是它們有非常快的執(zhí)行速度,這種快的執(zhí)行速度主要有以下兩個(gè)原因
        
            - 過濾器不會計(jì)算相關(guān)度的得分,所以它們在計(jì)算上更快一些
            - 過濾器可以被緩存到內(nèi)存中,這使得在重復(fù)的搜索查詢上,其要比相應(yīng)的查詢快出許多。
            
        為了理解過濾器,我們先來介紹“被過濾”的查詢,這使得你可以將一個(gè)查詢(像是match_all,match,bool等)和一個(gè)過濾器結(jié)合起來。作為一個(gè)例子,我們介紹一下范圍過濾器,它允許我們通過一個(gè)區(qū)間的值來過濾文檔。這通常被用在數(shù)字和日期的過濾上。
        
        這個(gè)例子使用一個(gè)被過濾的查詢,其返回值是越在20000到30000之間(閉區(qū)間)的賬戶。換句話說,我們想要找到越大于等于20000并且小于等于30000的賬戶。
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "query": {
                "filtered": {
                  "query": { "match_all": {} },
                  "filter": {
                    "range": {
                      "balance": {
                        "gte": 20000,
                        "lte": 30000
                      }
                    }
                  }
                }
              }
            }'
            
        分解上面的例子,被過濾的查詢包含一個(gè)match_all查詢(查詢部分)和一個(gè)過濾器(filter部分)。我們可以在查詢部分中放入其他查詢,在 filter部分放入其它過濾器。在上面的應(yīng)用場景中,由于所有的在這個(gè)范圍之內(nèi)的文檔都是平等的(或者說相關(guān)度都是一樣的),沒有一個(gè)文檔比另一個(gè)文檔 更相關(guān),所以這個(gè)時(shí)候使用范圍過濾器就非常合適了。
        
        通常情況下,要決定是使用過濾器還是使用查詢,你就需要問自己是否需要相關(guān)度得分。如果相關(guān)度是不重要的,使用過濾器,否則使用查詢。如果你有SQL背 景,查詢和過濾器在概念上類似于SELECT WHERE語句, although more so for filters than queries。
        
        除了match_all, match, bool,filtered和range查詢,還有很多其它類型的查uxn/過濾器,我們這里不會涉及。由于我們已經(jīng)對它們的工作原理有了基本的理解,將其應(yīng)用到其它類型的查詢、過濾器上也不是件難事。
        
    執(zhí)行聚合


        聚合提供了分組并統(tǒng)計(jì)數(shù)據(jù)的能力。理解聚合的最簡單的方式是將其粗略地等同為SQL的GROUP BY和SQL聚合函數(shù)。在Elasticsearch中,你可以在一個(gè)響應(yīng)中同時(shí)返回命中的數(shù)據(jù)和聚合結(jié)果。你可以使用簡單的API同時(shí)運(yùn)行查詢和多個(gè)聚 合,并以一次返回,這避免了來回的網(wǎng)絡(luò)通信,這是非常強(qiáng)大和高效的。
        
        作為開始的一個(gè)例子,我們按照state分組,按照州名的計(jì)數(shù)倒序排序:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "size": 0,
              "aggs": {
                "group_by_state": {
                  "terms": {
                    "field": "state"
                  }
                }
              }
            }'


        在SQL中,上面的聚合在概念上類似于:
           SELECT COUNT(*) from bank GROUP BY state ORDER BY COUNT(*) DESC
       
       響應(yīng)(其中一部分)是:
       
            "hits" : {
                "total" : 1000,
                "max_score" : 0.0,
                "hits" : [ ]
              },
              "aggregations" : {
                "group_by_state" : {
                  "buckets" : [ {
                    "key" : "al",
                    "doc_count" : 21
                  }, {
                    "key" : "tx",
                    "doc_count" : 17
                  }, {
                    "key" : "id",
                    "doc_count" : 15
                  }, {
                    "key" : "ma",
                    "doc_count" : 15
                  }, {
                    "key" : "md",
                    "doc_count" : 15
                  }, {
                    "key" : "pa",
                    "doc_count" : 15
                  }, {
                    "key" : "dc",
                    "doc_count" : 14
                  }, {
                    "key" : "me",
                    "doc_count" : 14
                  }, {
                    "key" : "mo",
                    "doc_count" : 14
                  }, {
                    "key" : "nd",
                    "doc_count" : 14
                  } ]
                }
              }
            }
            
        我們可以看到AL(abama)有21個(gè)賬戶,TX有17個(gè)賬戶,ID(daho)有15個(gè)賬戶,依此類推。
        
        注意我們將size設(shè)置成0,這樣我們就可以只看到聚合結(jié)果了,而不會顯示命中的結(jié)果。
        
        在先前聚合的基礎(chǔ)上,現(xiàn)在這個(gè)例子計(jì)算了每個(gè)州的賬戶的平均余額(還是按照賬戶數(shù)量倒序排序的前10個(gè)州):
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "size": 0,
              "aggs": {
                "group_by_state": {
                  "terms": {
                    "field": "state"
                  },
                  "aggs": {
                    "average_balance": {
                      "avg": {
                        "field": "balance"
                      }
                    }
                  }
                }
              }
            }'
            
        注意,我們把a(bǔ)verage_balance聚合嵌套在了group_by_state聚合之中。這是所有聚合的一個(gè)常用模式。你可以任意的聚合之中嵌套聚合,這樣你就可以從你的數(shù)據(jù)中抽取出想要的概述。
        
        基于前面的聚合,現(xiàn)在讓我們按照平均余額進(jìn)行排序:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "size": 0,
              "aggs": {
                "group_by_state": {
                  "terms": {
                    "field": "state",
                    "order": {
                      "average_balance": "desc"
                    }
                  },
                  "aggs": {
                    "average_balance": {
                      "avg": {
                        "field": "balance"
                      }
                    }
                  }
                }
              }
            }'
            
        下面的例子顯示了如何使用年齡段(20-29,30-39,40-49)分組,然后在用性別分組,然后為每一個(gè)年齡段的每一個(gè)性別計(jì)算平均賬戶余額:
        
            curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
            {
              "size": 0,
              "aggs": {
                "group_by_age": {
                  "range": {
                    "field": "age",
                    "ranges": [
                      {
                        "from": 20,
                        "to": 30
                      },
                      {
                        "from": 30,
                        "to": 40
                      },
                      {
                        "from": 40,
                        "to": 50
                      }
                    ]
                  },
                  "aggs": {
                    "group_by_gender": {
                      "terms": {
                        "field": "gender"
                      },
                      "aggs": {
                        "average_balance": {
                          "avg": {
                            "field": "balance"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }'
            
        有很多關(guān)于聚合的細(xì)節(jié),我們沒有涉及。如果你想做更進(jìn)一步的實(shí)驗(yàn),http://www.elasticsearch.org/guide/en /elasticsearch/reference/current/search-aggregations.html是一個(gè)非常好的起點(diǎn)。
        
        
    總結(jié)


        Elasticsearch既是一個(gè)簡單的產(chǎn)品,也是一個(gè)復(fù)雜的產(chǎn)品。我們現(xiàn)在已經(jīng)學(xué)習(xí)到了基礎(chǔ)部分,它的一些原理,以及怎樣用REST API來做一些工作。我希望這個(gè)教程已經(jīng)使你對Elasticsearch是什么有了一個(gè)更好的理解,跟重要的是,能夠激發(fā)你繼續(xù)實(shí)驗(yàn) Elasticsearch的其它特性。


    來自:
    http://blog.csdn.net/cnweike/article/details/33736429

    posted on 2015-07-16 15:51 狼愛上貍 閱讀(324) 評論(0)  編輯  收藏 所屬分類: elasticsearch

    主站蜘蛛池模板: 亚洲精品国精品久久99热一| 免费无遮挡无码视频网站| 十八禁在线观看视频播放免费| 精品一区二区三区免费毛片| 亚洲国产成人久久精品软件| 色老板亚洲视频免在线观| 亚洲国产精品无码久久久| 亚洲天堂电影在线观看| 亚洲成a人片在线观| 亚洲一区在线视频| 亚洲AV无码无限在线观看不卡| 亚洲国产日韩综合久久精品| 亚洲乱码在线观看| 亚洲最大的成人网站| 亚洲youwu永久无码精品| 在线视频亚洲一区| 日韩精品免费一线在线观看| 国产精品免费视频观看拍拍| 你懂的网址免费国产| 99精品视频在线观看免费专区| 69av免费观看| 成人在线视频免费| 免费在线观看日韩| 亚洲精品制服丝袜四区| 久久久久亚洲av无码专区| 久久精品国产亚洲av麻豆图片| 亚洲人成自拍网站在线观看| 黄色a级免费网站| 国内永久免费crm系统z在线| 91福利视频免费| 免费观看毛片视频| 亚洲性在线看高清h片| 亚洲av中文无码乱人伦在线r▽ | 久久精品私人影院免费看| 8888四色奇米在线观看免费看| 日韩欧美一区二区三区免费观看| 国产无遮挡吃胸膜奶免费看视频| 亚洲精品一级无码鲁丝片| 亚洲bt加勒比一区二区| 国产精品高清视亚洲一区二区| 黄色a三级免费看|