ElasticSearch聚合分析

聚合用于分析查詢結果集的統計指標,我們以觀看日志分析為例,介紹各種常用的ElasticSearch聚合操作。

目錄:

  • 查詢用戶觀看視頻數和觀看時長
  • 聚合分頁器
  • 查詢視頻uv
    • 單個視頻uv
    • 批量查詢視頻uv
  • Having查詢
    • 根據 count 進行過濾
    • 根據其它指標進行過濾

首先展示一下我們要分析的文檔結構:

{"video_id": 1289643545120062253, // 視頻id"video_uid": 3931482202390368051, // 視頻發布者id"uid": 47381776787453866, // 觀看用戶id"time": 1533891263224, // 時間發生時間"watch_duration": 30 // 觀看時長
}

每個文檔記錄了一個觀看事件,我們通過聚合分析用戶的觀看行為。

ElasticSearch引入了兩個相關概念:

  • 桶(Buckets): 滿足特定條件的文檔的集合
  • 指標(Metrics): 桶中文檔的統計值,如特定字段的平均值

查詢用戶觀看視頻數和觀看時長

首先用sql語句描述這個查詢:

SELECT uid, count(*) as view_count
FROM view_log
WHERE time >= #{since} AND time <= #{to} 
GROUP BY uid;

ES 查詢:

GET /view_log/_search
{"size" : 0,"query": {"range": {"time": {"gte": 0, // since"lte": 0 // to}}},"aggs": {"agg": { // agg為聚合的名稱"terms": { // 聚合的條件為 uid 相同"field": "uid"}}}
}

response:

{"took": 10,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 100000,"max_score": 0,"hits": []},"aggregations": {"agg": {"buckets": [{"key": 21836334489858688,"doc_count": 4026},{"key": 31489302390368051,"doc_count": 2717}]}
}

result.aggregations.agg.buckets列表中包含了查詢的結果。

因為我們按照terms:uid進行聚合,每個bucket為uid相同的文檔集合,key字段即為uid。

doc_count 字段表明bucket中文檔的數目即sql語句中的count(*) as view_count

我們可以為查詢添加額外的統計指標, sql描述:

SELECT uid, count(*) as view_count, avg(watch_duration) as avg_duration 
FROM view_log
WHERE time >= #{since} AND time <= #{to} 
GROUP BY uid;

ES 查詢:

GET /view_log/_search
{"size" : 0,"query": {"range": {"time": {"gte": 0, // since"lte": 0 // to}}},"aggs": {"agg": { // agg為聚合的名稱"terms": { // 聚合的條件為 uid 相同"field": "uid"},"aggs": { // 添加統計指標(Metrics)"avg_duration": { "avg": { // 統計 watch_duration 的平均值"field": "watch_duration" }}}}}
}

response:

{"took": 10,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 100000,"max_score": 0,"hits": []},"aggregations": {"agg": {"buckets": [{"key": 21836334489858688,"doc_count": 4026,"avg_duration": {"value": 12778.882352941177}},{"key": 31489302390368051,"doc_count": 2717,"avg_duration": {"value": 2652.5714285714284}}]}
}

avg_duration.value 表示 watch_duration 的平均值即該用戶的平均觀看時長。

聚合分頁器

在實際應用中用戶的數量非常驚人, 不可能通過一次查詢得到全部結果因此我們需要分頁器分批取回:

GET /view_log/_search
{"size" : 0,"query": {"range": {"time": {"gte": 0, // since"lte": 0 // to}}},"aggs": {"agg": { "terms": { "field": "uid","size": 10000, // bucket 的最大個數"include": { // 將聚合結果分為10頁,序號為[0,9], 取第一頁"partition": 0,"num_partitions": 10 }},"aggs": { "avg_duration": { "avg": { "field": "watch_duration" }}}}}
}

上述查詢與上節的查詢幾乎完全相同,只是在aggs.agg.terms字段中添加了include字段進行分頁。

查詢視頻uv

單個視頻uv

uv是指觀看一個視頻的用戶數(unique visit),與此相對沒有按照用戶去重的觀看數稱為pv(page visit)。

用SQL語句來描述:

SELECT video_id, count(*) as pv, count(distinct uid) as uv
FROM view_log
WHERE video_id = #{video_id};

ElasticSearch可以方便的進行count(distinct)查詢:

GET /view_log/_search
{"aggs": {"uv": {"cardinality": {"field": "uid"}}}
}

response:

{"took": 255,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 17579,"max_score": 0,"hits": []},"aggregations": {"uv": {"value": 11}}
}

批量查詢視頻uv

ElasticSearch也可以批量查詢count(distinct), 先用SQL進行描述:

SELECT video_id, count(*) as pv, count(distinct uid) as uv
FROM view_log
GROUP BY video_id;

查詢:

GET /view_log/_search
{"size": 0,"aggs": {"video": {"terms": {"field": "video_id"},"aggs": {"uv": {"cardinality": {"field": "uid"}}}}}
}

response:

{"took": 313,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 16940,"max_score": 0,"hits": []},"aggregations": {"video": {"buckets": [{"key": 25417499722062, // 視頻id"doc_count": 427, // 視頻觀看次數 pv"uv": {"value": 124 // 觀看視頻的用戶數 uv}},{"key": 72446898144,"doc_count": 744,"uv": {"value":233}}]}}
}

Having查詢

SQL可以使用HAVING語句根據聚合結果進行過濾,ElasticSearch可以使用pipeline aggregations達到此效果不過語法較為繁瑣。

根據 count 進行過濾

使用SQL查詢觀看超過200次的視頻:

SELECT video_id, count(*) as view_count
FROM view_log
GROUP BY video_id
HAVING count(*) > 200;
GET /view_log/_search
{"size": 0,"aggs": {"view_count": {"terms": {"field": "video_id"},"aggs": {"having": {"bucket_selector": {"buckets_path": { // 選擇 view_count 聚合的 doc_count 進行過濾"view_count": "_count"},"script": {"source": "params.view_count > 200"}}}}}}
}

response:

{"took": 83,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 775,"max_score": 0,"hits": []},"aggregations": {"view_count": {"buckets": [{"key": 35025417499764062,"doc_count": 529},{"key": 19913672446898144,"doc_count": 759}]}}
}

ElasticSearch實現類似HAVING查詢的關鍵在于使用bucket_selector選擇聚合結果進行過濾。

根據其它指標進行過濾

接下來我們嘗試查詢平均觀看時長大于5分鐘的視頻, 用SQL描述該查詢:

SELECT video_id FROM view_log
GROUP BY video_id
HAVING avg(watch_duration) > 300;
GET /view_log/_search
{"size": 0,"aggs": {"video": {"terms": {"field": "video_id"},"aggs": {"avg_duration": {"avg": {"field": "watch_duration"} },"avg_duration_filter": {"bucket_selector": {"buckets_path": {"avg_duration": "avg_duration"},"script": {"source": "params.avg_duration > 200"}}  }}}}
}

response:

{"took": 137,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 255,"max_score": 0,"hits": []},"aggregations": {"video": {"buckets": [{"key": 5417499764062,"doc_count": 91576,"avg_duration": {"value": 103}},{"key": 19913672446898144,"doc_count": 15771,"avg_duration": {"value": 197}}]}}
}

轉載于:https://www.cnblogs.com/Finley/p/9499534.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/397169.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/397169.shtml
英文地址,請注明出處:http://en.pswp.cn/news/397169.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

bg感_【0328】BG推文 | 5本我在逃生游戲里養娃娃+歲月繾綣已無你+關于我比女主蘇這回事+消失的白月光又回來了等...

大家多多支持原文&#xff01;以下內容多為網絡搜集&#xff0c;非商業用途。版權歸原作者所有&#xff0c;侵聯&#xff01;BG文《我在逃生游戲里養娃娃》作者&#xff1a;鶴舫閑人《歲月繾綣已無你》作者&#xff1a;酒爺《關于我比女主蘇這回事》作者&#xff1a;歡何極《消…

android 屏幕最小寬度_AndroidTV屏幕適配-smallestWidth(最小寬度) 限定符

背景前幾天接到一個需求&#xff0c;把項目上的原來的2k屏幕適配到4k屏幕。我采用的是smallestWidth最小寬度限定符進行適配的我們項目的。1&#xff0c;smallestWidth 限定符適配原理系統都是根據限定符去尋找對應的 dimens.xml 文件。例如在最小寬度為 720dp 的設備上&#x…

mysql 組合索引

MySQL單列索引是我們使用MySQL數據庫中經常會見到的&#xff0c;MySQL單列索引和組合索引的區別可能有很多人還不是十分的了解&#xff0c;下面就為您分析兩者的主要區別&#xff0c;供您參考學習。 為了形象地對比兩者&#xff0c;再建一個表&#xff1a; CREATE TABLE myInde…

cmake使用總結(轉)---工程主目錄CMakeList文件編寫

在linux 下進行開發很多人選擇編寫makefile 文件進行項目環境搭建&#xff0c;而makefile 文件依賴關系復雜&#xff0c;工作量很大&#xff0c;搞的人頭很大。采用自動化的項目構建工具cmake 可以將程序員從復雜的makefile 文件中解脫出來。cmake 根據內置的規則和語法來自動生…

微信開發者工具 wxmi修改模版顏色_十款高效好用的在線網頁工具,提升你的辦公效率...

大家好&#xff0c; 我是阿毛&#xff0c;今天給大家推薦高效辦公的10個在線網頁工具&#xff0c;可以不用下載安裝很多app&#xff0c;也不用在電腦上裝很多軟件。在線制作精彩視頻操作非常簡單&#xff0c;選擇模板&#xff0c;上傳照片然后點擊制作等待完成就可以了&#xf…

三星ml1660拆機圖解_三星s6拆機圖解介紹

三星s6拆機圖解介紹三星s6怎么拆機?不管你是手機維修者還是狂熱的手機玩家&#xff0c;相信對您手中的三星s6內部構造和組裝步驟應該都是非常有興趣的吧?今天綠茶通過Fixit發布的三星s6拆機教程來和大家一起分享一下三星s6拆機步驟&#xff0c;從三星s6的內部構造一起來了解一…

Ajax請求利用jsonp實現跨域

跨域: js有一個同源限制,簡單說來源不一樣的話就無法相互間交互.那么怎么算來源不一樣呢, 舉個例子:瀏覽器訪問-->服務器A--->得到頁面A---頁面A中的js腳本只能訪問服務器A的資源(相同域名和端口,此外域名與對應的ip也算不同源,要么都域名,要么都ip). 以上就是js的跨域問…

[轉]使用Navicat for Oracle工具連接oracle的

使用Navicat for Oracle工具連接oracle的 這是一款oracle的客戶端的圖形化管理和開發工具&#xff0c;對于許多的數據庫都有支持。之前用過 Navicat for sqlserver,感覺很好用&#xff0c;所以下載了Oracle版的用。上網查看了一下這個工具可以用于任何版本 8i 或以上的 Oracle …

微信小程序基于第三方插件微信同聲傳譯,以及一些問題解決辦法

使用之前首先得在微信微信小程序后臺添加插件&#xff0c;獲取插件的appid 名稱 使用時在app.json文件添加插件配置 1 plugins: { 2 WechatSI: { 3 version: 0.1.0, 4 provider: wx069ba97219f66d99 5 } 6 } 其次就是在使用的頁面進行調用 在index.js外…

TF卡里刪掉文件后內存沒變大_內存卡損壞怎么修復?數據恢復方法教程

內存卡損壞怎么修復&#xff1f;內存卡又叫SD卡&#xff0c;是一種很輕便小巧的便攜存儲裝置&#xff0c;往往內置于各種便攜媒體設備內部。內存卡本身具有堅固、抗沖擊等外部特性和讀寫快、空間大等內部特性&#xff0c;但是內存卡因為每天都要讀寫大量數據很容易從內部發生損…

apollo持久化sentinel_Spring Cloud Alibaba基礎教程:Sentinel使用Apollo存儲規則

上一篇我們介紹了如何通過Nacos的配置功能來存儲限流規則。Apollo是國內用戶非常多的配置中心&#xff0c;所以&#xff0c;今天我們繼續說說Spring Cloud Alibaba Sentinel中如何將流控規則存儲在Apollo中。使用Apollo存儲限流規則Sentinel自身就支持了多種不同的數據源來持久…

Lintcode: Unique Paths

C dp 遞推式&#xff1a;dp[i][j] dp[i-1][j] dp[i][j-1] 初值&#xff1a;dp[i][j] 1&#xff0c;i0 or j0 空間優化&#xff1a;省掉一維 1 class Solution {2 public:3 /**4 * param n, m: positive integer (1 < n ,m < 100)5 * return an integer6…

idea 如何隱藏/展示不想看到的文件

隱藏&#xff1a;在 Ignore files and folders中添加想要過濾的文件或文件夾名稱 展示隱藏文件&#xff1a; 在過濾列表中刪除掉文件或者文件夾就好了 轉載于:https://www.cnblogs.com/mengjianzhou/p/6177897.html

BZOJ2286: [Sdoi2011]消耗戰(虛樹)

BZOJ2286: [Sdoi2011]消耗戰 Time Limit: 20 Sec   Memory Limit: 512 MB Description 在一場戰爭中&#xff0c;戰場由n個島嶼和n-1個橋梁組成&#xff0c;保證每兩個島嶼間有且僅有一條路徑可達。現在&#xff0c;我軍已經偵查到敵軍的總部在編號為1的島嶼&#xff0c;而且…

Java基礎知識:Java實現Map集合二級聯動4

comboBox.setModel(new DefaultComboBoxModel(getProvince())); // 添加省份信息 final JLabel label new JLabel(); label.setText("省/直轄市"); label.setBounds(155, 30, 66, 18); panel.add(label); final JLabel label_1 new JLabel(); label_1.setText(&quo…

linux QT 結束當前進程_Qt編寫控件屬性設計器7-串口采集

一、前言數據源是組態軟件的核心靈魂&#xff0c;少了數據源&#xff0c;組態就是個花架子沒卵用&#xff0c;一般數據源有三種方式獲取&#xff0c;串口、網絡、數據庫&#xff0c;至于數據規則是什么&#xff0c;這個用戶自己指定&#xff0c;本設計器全部采用第一個字節作為…

magento2郵件調試方法

order mail 直接打印到頁面上 位置 vendor\magento\module-sales\Model\Order\Email\Sender.php Magento\Sales\Model\Order\Email\Sender::prepareTemplate() 添加代碼 $objectManager \Magento\Framework\App\ObjectManager::getInstance(); $templateFactory $objectManag…

python多進程怎么樣_Python執行多進程任務的方法

Python的多進程可以借助from multiprocessing import Pool來實現。簡而言之分為這樣幾步&#xff1a;導入包from multiprocessing import Pool編寫任務函數。def 任務函數(參數)實例化進程池并設置進程數。poolPool(欲設置的進程數)開始布置任務&#xff0c;把多個任務添加進多…

JAVA多線程之Synchronize 關鍵字原理

image眾所周知 Synchronize 關鍵字是解決并發問題常用解決方案&#xff0c;有以下三種使用方式: 同步普通方法&#xff0c;鎖的是當前對象。同步靜態方法&#xff0c;鎖的是當前 Class 對象。同步塊&#xff0c;鎖的是 {} 中的對象。實現原理&#xff1a;JVM 是通過進入、退出對…

iOS-數據持久化-第三方框架FMDB的使用

FMDB簡單介紹 一、簡單說明 1.什么是FMDB FMDB是iOS平臺的SQLite數據庫框架 FMDB以OC的方式封裝了SQLite的C語言API 2.FMDB的優點 使用起來更加面向對象&#xff0c;省去了很多麻煩、冗余的C語言代碼 對比蘋果自帶的Core Data框架&#xff0c;更加輕量級和靈活 提供了多線程安全…