2
我正在使用MongoDB數據庫來跟蹤應用程序的分析。我正在編寫一個Clojure應用程序(使用clj-time和Monger)從數據庫中獲取數據。根據特定時區,是否有一種按日期分組記錄的有效方法?
我有一個包含記錄的集合像
{"_id": ObjectId(...),
timestamp: ISODate("2013-06-01T15:18:37Z"),
device: "04dbf04b6dc0d0a4fd383967b3dc62f50111e07e"}
每個不同device
代表我公司的服務不同的用戶。我想要做的是找出我每天有多少(獨特)用戶,但是我希望「日」能特別提及美國/中央時區,並將夏令時考慮在內。 (如果這是不是一個要求,我認爲我可以做一些像$group
然後distinct
。)
這就是我一直在做:
(ns analytics.reporting
(:use [monger.core :only [connect! connect set-db! get-db]]
monger.operators
clj-time.core
clj-time.periodic
clj-time.format)
(:require [monger.collection :as mc]))
(defn to-central
[dt]
(from-time-zone dt (time-zone-for-id "America/Chicago")))
(defn count-distinct
[coll]
(count (distinct coll)))
(defn daily-usage
[ndays]
(let [midnights (map to-central
(reverse (for [offset (map days (range ndays))]
(minus (to-central (today-at 0 0)) offset))))
by-day (for [midnight midnights]
(mc/find-maps "devices" {:timestamp {$gte midnight $lt (plus midnight (days 1))}}))
devices-by-day (map #(map :device %) by-day)
distinct-devices-by-day (map count-distinct devices-by-day)]
distinct-devices-by-day))
如果您無法讀取的Clojure ,這基本上是這樣說的:獲得中央時區最近的n midnights的列表,然後運行Mongo查詢以查找每個連續的中午之間的所有記錄。然後,計算每天內不同的device
s的數量。
這裏就是我不喜歡這種方法:
- 運行一個單獨的查詢每一天(我一般看30天時間)感覺錯;這是應該在數據庫端而不是應用端完成的。
- 計數不同的
device
也應該由數據庫完成。 - 我的服務器設置爲UTC時區,因此如果它是在UTC的午夜之後但在中央時間的午夜之前,則此列表中的最後一個條目將始終爲零。這很容易修補,但我更喜歡一個足夠聰明的解決方案,以防止它擺在首位。
- 這整個功能需要約500ms運行。這並不糟糕 - 我是唯一一個運行查詢的人,每天只有一次或兩次 - 但似乎操作不應該花費那麼長時間。
有沒有辦法讓更多這種邏輯進入MongoDB查詢?
一種方法是修改數據以包含日期作爲中央時間。或者,您可能可以編寫MapReduce來計算總計。你嘗試過嗎? – WiredPrairie