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 미드 나이트의 목록을 중앙 시간대에서 가져온 다음 Mongo 쿼리를 실행하여 각각의 연속적인 쌍의 중창 사이의 모든 레코드를 찾습니다. 그런 다음 각 일 내에 별개의 device
수를 계산하십시오. 여기
- 을; 이것은 응용 프로그램 측 대신 데이터베이스 측에서 수행해야하는 작업입니다.
device
을 구별하는 작업은 데이터베이스에서 수행해야합니다.- 내 서버는 UTC 시간대로 설정되어 있으므로 중부 표준시 자정 이후 자정 이전 인 경우이 목록의 마지막 항목은 항상 0입니다. 이것은 패치하기에 충분히 쉽지만 처음에는 그것을 막을만큼 똑똑한 솔루션을 선호합니다.
- 이 전체 기능을 실행하는 데 약 500ms가 걸립니다. 그것은 끔찍한 것이 아닙니다. 저는 쿼리를 실행하는 유일한 사람이고, 하루에 한두 번만 실행합니다.하지만 오랜 시간이 걸리지 않아야하는 것처럼 보입니다.
이 논리를 MongoDB 쿼리에 더 많이 적용 할 수있는 방법이 있습니까?
한 가지 방법은 날짜를 중앙 시간으로 포함하도록 데이터를 수정하는 것입니다. 또는 MapReduce를 작성하여 합계를 계산할 수도 있습니다. 너 그거 해봤 니? – WiredPrairie