1. 程式人生 > >ElasticSearch5.X搜尋條件的聚合(六)

ElasticSearch5.X搜尋條件的聚合(六)

範圍限定的聚合編輯

聚合可以與搜尋請求同時執行,但是我們需要理解一個新概念: 範圍 。 預設情況下,聚合與查詢是對同一範圍進行操作的,也就是說,聚合是基於我們查詢匹配的文件集合進行計算的。

讓我們看看第一個聚合的示例:

GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color"
            }
        }
    }
}

我們可以看到聚合是隔離的。現實中,Elasticsearch 認為 "沒有指定查詢" 和 "查詢所有文件" 是等價的。前面這個查詢內部會轉化成下面的這個請求:

GET /cars/transactions/_search
{
    "size" : 0,
    "query" : {
        "match_all" : {}
    },
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color"
            }
        }
    }
}

因為聚合總是對查詢範圍內的結果進行操作的,所以一個隔離的聚合實際上是在對 match_all 的結果範圍操作,即所有的文件。

一旦有了範圍的概念,我們就能更進一步對聚合進行自定義。我們前面所有的示例都是對 所有

 資料計算統計資訊的:銷量最高的汽車,所有汽車的平均售價,最佳銷售月份等等。

利用範圍,我們可以問“福特在售車有多少種顏色?”諸如此類的問題。可以簡單的在請求中加上一個查詢(本例中為 match 查詢):

GET /cars/transactions/_search
{
    "query" : {
        "match" : {
            "make" : "ford"
        }
    },
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color"
            }
        }
    }
}

因為我們沒有指定 "size" : 0 ,所以搜尋結果和聚合結果都被返回了:

{
...
   "hits": {
      "total": 2,
      "max_score": 1.6931472,
      "hits": [
         {
            "_source": {
               "price": 25000,
               "color": "blue",
               "make": "ford",
               "sold": "2014-02-12"
            }
         },
         {
            "_source": {
               "price": 30000,
               "color": "green",
               "make": "ford",
               "sold": "2014-05-18"
            }
         }
      ]
   },
   "aggregations": {
      "colors": {
         "buckets": [
            {
               "key": "blue",
               "doc_count": 1
            },
            {
               "key": "green",
               "doc_count": 1
            }
         ]
      }
   }
}

看上去這並沒有什麼,但卻對高大上的儀表盤來說至關重要。 加入一個搜尋欄可以將任何靜態的儀表板變成一個實時資料搜尋裝置。 這讓使用者可以搜尋資料,檢視所有實時更新的圖形(由於聚合的支援以及對查詢範圍的限定)。 這是 Hadoop 無法做到的!

Java程式碼實現:

/**
  	  * Description:帶有搜尋條件的聚合查詢
  	  * 例:bmw(寶馬)在售車有多少種顏色
  	  * 
  	  * @author wangweidong
  	  * CreateTime: 2017年11月10日 下午4:03:30
  	  *
  	 */
  	@Test
  	public void searchBucketsAggregation() {
  		String index = "cars";
  		String type = "transactions";
  		SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type);
  		
  		//搜尋條件
  		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
  		queryBuilder.must(QueryBuilders.matchQuery("make", "bmw")); 
  		
  		//聚合
	    TermsAggregationBuilder field = AggregationBuilders.terms("popular_colors").field("color.keyword");
	    searchRequestBuilder.addAggregation(field);
//	    searchRequestBuilder.setSize(0);
	    searchRequestBuilder.setQuery(queryBuilder);
	    SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
	     
	    System.out.println(searchResponse.toString());
	    
	    Terms genders = searchResponse.getAggregations().get("popular_colors");
	    for (Terms.Bucket entry : genders.getBuckets()) {
	    	Object key = entry.getKey();      // Term
	        Long count = entry.getDocCount(); // Doc count
	        
	        System.out.println(key);
	        System.out.println(count);
	    }
  	}

全域性桶編輯

通常我們希望聚合是在查詢範圍內的,但有時我們也想要搜尋它的子集,而聚合的物件卻是 所有 資料。

例如,比方說我們想知道福特汽車與 所有 汽車平均售價的比較。我們可以用普通的聚合(查詢範圍內的)得到第一個資訊,然後用 全域性 桶獲得第二個資訊。

全域性 桶包含 所有 的文件,它無視查詢的範圍。因為它還是一個桶,我們可以像平常一樣將聚合巢狀在內:

GET /cars/transactions/_search
{
    "size" : 0,
    "query" : {
        "match" : {
            "make" : "ford"
        }
    },
    "aggs" : {
        "single_avg_price": {
            "avg" : { "field" : "price" } 
        },
        "all": {
            "global" : {}, 
            "aggs" : {
                "avg_price": {
                    "avg" : { "field" : "price" } 
                }

            }
        }
    }
}

聚合操作在查詢範圍內(例如:所有文件匹配 ford )

global 全域性桶沒有引數。

聚合操作針對所有文件,忽略汽車品牌。

single_avg_price 度量計算是基於查詢範圍內所有文件,即所有 福特 汽車。avg_price 度量是巢狀在 全域性 桶下的,這意味著它完全忽略了範圍並對所有文件進行計算。聚合返回的平均值是所有汽車的平均售價。

如果能一直堅持讀到這裡,應該知道我們有個真言:儘可能的使用過濾器。它同樣可以應用於聚合,在下一章中,我們會展示如何對聚合結果進行過濾而不是僅對查詢範圍做限定。

Java程式碼實現:

/**
  	 * Description:全域性桶
  	 * 例:想知道福特(ford)汽車與 所有 汽車平均售價的比較
  	 * 
  	 * @author wangweidong
  	 * CreateTime: 2017年11月10日 下午4:03:30
  	 *
  	 */
  	@Test
  	public void globalBucketsAggregation() {
  		try {
  			String index = "cars";
  	  		String type = "transactions";
  	  		SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type);
  	  		
  	  		//搜尋條件
  	  		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
  	  		queryBuilder.must(QueryBuilders.matchQuery("make", "ford")); 
  	  		
  	  		//平均價格
  	  		AvgAggregationBuilder singleAvgPrice = AggregationBuilders.avg("single_avg_price").field("price");
  	  		
  	  		//聚合
  	  		GlobalAggregationBuilder field = AggregationBuilders.global("all");
  	        AvgAggregationBuilder avgPrice = AggregationBuilders.avg("avg_price").field("price");
  	        field.subAggregation(avgPrice);
  	  		
  	        searchRequestBuilder.addAggregation(singleAvgPrice);
  	  		searchRequestBuilder.addAggregation(field);
  		    searchRequestBuilder.setSize(0);
  	  		searchRequestBuilder.setQuery(queryBuilder);
  	  		SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
  	  		
  	  		System.out.println(searchResponse.toString());
  	  		
  	  		Avg avg = searchResponse.getAggregations().get("single_avg_price");
  	  		System.out.println("福特(ford)汽車平均價格:" + avg.getValue());
  	  		
  	  		Global global = searchResponse.getAggregations().get("all");
  	  		Avg allAvg = global.getAggregations().get("avg_price");
  	  		System.out.println("所有汽車平均價格:" + allAvg.getValue());
		} catch (Exception e) {
			e.printStackTrace();
		}
  	}

相關推薦

ElasticSearch5.X搜尋條件聚合

範圍限定的聚合編輯 聚合可以與搜尋請求同時執行,但是我們需要理解一個新概念: 範圍 。 預設情況下,聚合與查詢是對同一範圍進行操作的,也就是說,聚合是基於我們查詢匹配的文件集合進行計算的。 讓我們看看第一個聚合的示例: GET /cars/transa

從PRISM開始學WPFMVVM事件聚合器EventAggregator?

rec 行動 manage using panel mark 控件 lock object 從PRISM開始學WPF(一)WPF? 從PRISM開始學WPF(二)Prism? 從PRISM開始學WPF(三)Prism-Region? 從PRISM開始學WPF(四)Prism

Webpack 4.X 從入門到精通 - 第三方庫

ofo 分享 ctype mod 找到 ebp 問題 title 效率 在開發的時候會時常用到第三方的庫或者框架,比如耳熟能詳的jquery。借助它們能提高開發效率,但是如何在webpack中使用呢。這篇文章介紹兩個東西,如何使用第三方庫以及如何提取第三方庫。 使用第三方庫

ElasticSearch最佳入門實踐案例實戰之電商網站商品管理:多種搜尋方式

1、query string search 搜尋全部商品 took:耗費了幾毫秒 timed_out:是否超時,這裡是沒有 _shards:資料拆成了5個分片,所以對於搜尋請求,會打到所有的primary shard(或者是它的某個replica shard也可以) hits.tot

【遊戲開發】關於Direct X繪製蝙蝠著色器

//D3D相容庫,包含對系統的相容以及Directx庫 #include "DXUT.h" //攝像機 #include "DXUTcamera.h" //設定對話 #include "DXUTsettingsdlg.h" //音樂 #include "SDKmisc.h" //資源 #in

Cocos2d-x學習筆記例項——多層佈景

【關於多層佈景】 在遊戲開發中,一般會把遊戲分為兩部分:一部分是遊戲介面部分,也就是常說得UI部分;另一部分就是遊戲本身部分。有時UI有很多頁面,在頁面中用的圖也不是很多,不需要進行場景切換,只需把不同頁面做成不同的佈景,然後切換佈景層。那麼就需要一個“管理者”來管理這些介面,這時

從頭開始寫專案Makefile:引數傳遞、條件判斷、include

在多個Makefile巢狀呼叫時,有時我們需要傳遞一些引數給下一層Makefile。比如我們在頂層Makefile裡面定義的開啟除錯資訊變數DEBUG_SYMBOLS,我們希望在進入子目錄執行子Makefile時該變數仍然有效,這是需要將該變數傳遞給子Makefile,那怎麼傳遞呢?這裡有兩種方法:

springboot + mybatis plus實現多表聯查分頁3.X版本

註明 : 上兩篇文章我們講解了springboot+mybatis-plus對於單表的CRUD和條件構造器的使用方法,但是對於我們的實戰專案中多表聯查也是經常會出現的。今天我們就來說下怎麼在springboot+MP模式下實現多表聯查並分頁。 MP推薦使用的是

圖解演算法學習筆記:廣度優先搜尋

本章內容;        學習使用新的資料結構圖來建立網路模型;        學習廣度優先搜尋;        學習有向圖和無向圖;        學習拓撲排序,這種排序演算法指出了節點之間的依賴關係。 1)圖簡介 假設你住在舊金山,要從雙子峰前往金門大橋。你想乘

pandas系列學習:資料聚合

作者:chen_h 微訊號 & QQ:862251340 微信公眾號:coderpai 我最近一直在探索的一個方面是通過不同變數對大型資料幀進行分組,以及對每個組應用匯總函式的任務。這是在 pandas 中使用 DataFrame 物件的

Spring Boot 2.x:優雅的統一返回值

為什麼要統一返回值 在我們做後端應用的時候,前後端分離的情況下,我們經常會定義一個數據格式,通常會包含code,message,data這三個必不可少的資訊來方便我們的交流,下面我們直接來看程式碼 ReturnVO package indi.viyoung.viboot.util; import ja

Vue條件與循環

根據 var 電梯 user team 不同的 see script img 1.條件(v-if) 控制切換一個元素是否顯示 <div id="app-3"> <p v-if="seen">現在你看到我了</p> </div&

Vue條件與迴圈

1.條件(v-if) 控制切換一個元素是否顯示 <div id="app-3"> <p v-if="seen">現在你看到我了</p> </div> <script> var app3 = new Vue({ el: '#app-3

《Linux系統》之"皮毛系列" 檔案搜尋相關命令

為什麼要使用搜索命令呢? 第一:隨著時間的流逝,檔案系統中的檔案越來越多,我們不可能記住所有檔案的位置或內容(除非你是天才中的天才,呵呵呵)。 第二:不同版本的Linux,系統檔案或者是應用程式所需要的檔案的儲存位置可能會有所差別。 因此Linux系統提供了一些檔案搜尋命令,供

Hadoop入門進階步步高-Hadoop1.x與Hadoop2的區別

六、Hadoop1.x與Hadoop2的區別1、變更介紹Hadoop2相比較於Hadoop1.x來說,HDFS的架構與MapReduce的都有較大的變化,且速度上和可用性上都有了很大的提高,Hadoop2中有兩個重要的變更:l HDFS的NameNodes可以以叢集的方式佈署

分散式搜尋elasticsearch java API 之------批量新增刪除索引

elasticsearch支援批量新增或刪除索引文件,java api裡面就是通過構造BulkRequestBuilder,然後把批量的index/delete請求新增到BulkRequestBuilder裡面,執行BulkRequestBuilder。下面是個例子: im

elasticsearch5.x系列之四索引模板的使用,詳細得不要不要的

1,首先看一下下面這個索引模板 curl -XPUT "master:9200/_template/template_1?pretty" -H 'Content-Type: application/json' -d' ---> 模板名字叫做temp

Elasticsearch瞭解全文搜尋

遇到的問題 通過前面的學習,我們已經可以使用elasticsearch來進行資料的搜尋了,但此時我們發現了一個問題,這個問題如果沒有解決好就很影響我們後續的使用,那麼該問題是什麼呢?我們來看一下: 上面的截圖是我搜索“在”關鍵字出來的結果,按照正常情況下,我們是不是不應該搜

遍歷聚合物件中的元素——迭代器模式

6 迭代器模式總結 迭代器模式是一種使用頻率非常高的設計模式,通過引入迭代器可以將資料的遍歷功能從聚合物件中分離出來,聚合物件只負責儲存資料,而遍歷資料由迭代器來完成。由於很多程式語言的類庫都已經實現了

ElasticStack學習:ElasticSearch搜尋初探

一、ElasticSearch搜尋介紹   1、ElasticSearch搜尋方式主要分為以下兩種:     1)、URI Search:此種查詢主要是使用Http的Get方法,在URL中使用查詢引數進行查詢;     如:http://localhost:9200/kibana_sample