MongoDB 聚合分組取第一條記錄的案例及實現

来源:https://www.cnblogs.com/xuliuzai/archive/2019/01/22/10306578.html
-Advertisement-
Play Games

關鍵字:MongoDB; aggregate;forEach 今天開發同學向我們提了一個緊急的需求,從集合mt_resources_access_log中,根據欄位refererDomain分組,取分組中最近一筆插入的數據,然後將這些符合條件的數據導入到集合mt_resources_access_l ...


關鍵字:MongoDB; aggregate;forEach

今天開發同學向我們提了一個緊急的需求,從集合mt_resources_access_log中,根據欄位refererDomain分組,取分組中最近一筆插入的數據,然後將這些符合條件的數據導入到集合mt_resources_access_log_new中。

接到這個需求,還是有些心虛的,原因有二,一是,業務需要,時間緊;二是,實現這個功能MongoDB聚合感覺有些複雜,聚合要走好多步。

數據記錄格式如下:

記錄1

{
    "_id" : ObjectId("5c1e23eaa66bf62c0c390afb"),
    "_class" : "C1",
    "resourceUrl" : "/static/js/p.js",
    "refererDomain" : "1234",
    "resourceType" : "static_resource",
    "ip" : "17.17.13.13",
    "createTime" : ISODate("2018-12-22T19:45:46.015+08:00"),
    "disabled" : 0
}

記錄2

{
    "_id" : ObjectId("5c1e23eaa66bf62c0c390afb"),
    "_class" : "C1",
    "resourceUrl" : "/static/js/p.js",
    "refererDomain" : "1234",
    "resourceType" : "Dome_resource",
    "ip" : "17.17.13.14",
    "createTime" : ISODate("2018-12-21T19:45:46.015+08:00"),
    "disabled" : 0
}

記錄3

{
    "_id" : ObjectId("5c1e23eaa66bf62c0c390afb"),
    "_class" : "C2",
    "resourceUrl" : "/static/js/p.js",
    "refererDomain" : "1235",
    "resourceType" : "static_resource",
    "ip" : "17.17.13.13",
    "createTime" : ISODate("2018-12-20T19:45:46.015+08:00"),
    "disabled" : 0
}

記錄4

{
    "_id" : ObjectId("5c1e23eaa66bf62c0c390afb"),
    "_class" : "C2",
    "resourceUrl" : "/static/js/p.js",
    "refererDomain" : "1235",
    "resourceType" : "Dome_resource",
    "ip" : "17.17.13.13",
    "createTime" : ISODate("2018-12-20T19:45:46.015+08:00"),
    "disabled" : 0
}
 

以上是我們的4條記錄,類似的記錄文檔有1500W。

因為情況特殊,業務發版需要這些數據。催的比較急,而 通過 聚合 框架aggregate,短時間有沒有思路, 所以,當時就想著嘗試採用其他方案。

最後,問題處理方案如下。

Step 1  通過聚合框架 根據條件要求先分組,並將新生成的數據輸出到集合mt_resources_access_log20190122 中(共產生95筆數據);

實現代碼如下:

db.log_resources_access_collect.aggregate(
                     [
                      
                       { $group: { _id: "$refererDomain" } },
                       { $out : "mt_resources_access_log20190122" }
                     ]
  
                   )

Step 2  通過2次 forEach操作,迴圈處理 mt_resources_access_log20190122和mt_resources_access_log的數據。

代碼解釋,處理的邏輯為,迴圈逐筆取出mt_resources_access_log20190122的數據(共95筆),每筆逐行加工處理,處理的邏輯主要是  根據自己的_id欄位數據(此欄位來自mt_resources_access_log聚合前的refererDomain欄位), 去和 mt_resources_access_log的欄位 refererDomain比對,查詢出符合此條件的數據,並且是按_id 倒序,僅取一筆,最後將Join刷選後的數據Insert到集合mt_resources_access_log_new。

新集合也是95筆數據。

大家不用擔心性能,查詢語句在1S內實現了結果查詢。

db.mt_resources_access_log20190122.find({}).forEach(
    function(x) {
        db.mt_resources_access_log.find({ "refererDomain": x._id }).sort({ _id: -1 }).limit(1).forEach(
            function(y) {
                db.mt_resources_access_log_new.insert(y)
            }
        )
    }
)

 

Step 3 查詢驗證新產生的集合mt_resources_access_log_new,結果符合業務要求。 

刷選前集合mt_resources_access_log的數據量為1500多W。

刷選後產生新的集合mt_resources_access_log_new 數據量為95筆。

 

註意:根據時間排序的要求,因為部分文檔沒有createTime欄位類型,且 createTime欄位上沒有創建索引,所以未了符合按時間排序我們採用了sort({_id:1})的變通方法,因為_id 還有時間的意義。下麵的內容為MongoDB對應_id 的相關知識。

最重要的是前4個位元組包含著標準的Unix時間戳。後面3個位元組是機器ID,緊接著是2個位元組的進程ID。最後3個位元組存儲的是進程本地計數器。計數器可以保證同一個進程和同一時刻內不會重覆。

 

本文版權歸作者所有,未經作者同意不得轉載,謝謝配合!!!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • VirtualBox安裝centos7配置靜態ip地址可以本機訪問,可以聯網。 在開始之前先說一下,不知道為什麼,我在網上百度的大多數是不能用的,或者只能主機訪問,或者只能聯網。 我的配置文件為ifcfg-enp0s3 話不多說:上圖 1.安裝完centos7之後進入 2.選擇設置 >網路 如下圖可 ...
  • 本文收錄在容器技術學習系列文章總目錄 1、kubernetes安裝介紹 1.1 K8S架構圖 1.2 K8S搭建安裝示意圖 1.3 安裝kubernetes方法 優點:你只要安裝kubeadm即可;kubeadm會幫你自動部署安裝K8S集群;如:初始化K8S集群、配置各個插件的證書認證、部署集群網路 ...
  • 命令: cp 對應英文: copy 作用: 複製文件或目錄 選項: -f:已存在的目標文件直接覆蓋,不會提示 -i:覆蓋文件前提示,接著輸入 y 或 n -r:若給出的源文件是目錄文件,則cp將遞歸複製該目錄下的所有子目錄和文件,目標文件必須是一個目錄名 用法: cp [選項] 源文件 目標文件 # ...
  • #字元串比較if [ "$1" == "判斷條件" ] then echo "$1" elif [ "$1" == "判斷條件" ] then echo "$1" else echo '[提示信息]' fi#數值比較int1 -eq int2 兩數相等為真int1 -ne int2 兩數不等為真in ...
  • 一 Ansible的安裝部署 1.1 PIP方式 略,可參考《001.Pip簡介及使用》。 提示:建議將PIP升級到最新:pip install --upgrade pip。 1.2 YUM方式 二 Ansible目錄及配置 2.1 Ansible目錄結構 配置文件目錄:/etc/ansible 主 ...
  • #日期時間 echo '日期時間' datetime=$(date "+%Y-%m-%d %H:%M:%S") echo "$datetime" ...
  • 前言 開心一刻 和朋友去吃小龍蝦,隔壁桌一個小女孩問媽媽:"媽媽,小龍蝦回不了家,它媽媽會不會著急?" 她媽媽愣住了,我扒蝦的手停下了,這麼善良的問題,怎麼下得了口。這是老闆急忙過來解圍:"不會的,不會的,它們全家都在這了。" 路漫漫其修遠兮,吾將上下而求索! github:https://gith ...
  • 創建資料庫架構註意事項 包含 CREATE SCHEMA AUTHORIZATION 但未指定名稱的語句僅允許用於向後相容性。 該語句未引起錯誤,但未創建一個架構。 包含 CREATE SCHEMA AUTHORIZATION 但未指定名稱的語句僅允許用於向後相容性。 該語句未引起錯誤,但未創建一個 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...