|
7 | 7 |
|
8 | 8 | (defn metric-query |
9 | 9 | "Generic select query function for returning analytics data from the events table" |
10 | | - [ds {:keys [select order-by group-by metric feed-id post-id content-type-id bundle-id creator-id distributor-id min-date max-date category-ids ret]}] |
| 10 | + [ds {:keys [select order-by group-by limit metric feed-id post-id content-type-id bundle-id creator-id distributor-id min-date max-date category-ids where ret]}] |
11 | 11 | (let [clauses (cond-> {} |
12 | 12 | (some? metric) (hsql/where [:= :event metric]) |
13 | 13 | (some? feed-id) (hsql/where [:= :feed-id feed-id]) |
|
16 | 16 | (some? bundle-id) (hsql/where [:= :bundle-id bundle-id]) |
17 | 17 | (some? creator-id) (hsql/where [:= :creator-id creator-id]) |
18 | 18 | (some? distributor-id) (hsql/where [:= :distributor-id distributor-id]) |
| 19 | + (some? where) (merge where) |
19 | 20 | (and (some? min-date) (nil? max-date)) (hsql/where [:>= :timestamp min-date]) |
20 | 21 | (and (some? max-date) (nil? min-date)) (hsql/where [:<= :timestamp max-date]) |
21 | 22 | (and (some? min-date) (some? max-date)) (hsql/where [:between :timestamp min-date max-date]) |
22 | 23 | (some? select) (merge select) |
| 24 | + (nil? select) (merge {:select [[[:count :*] :total]]}) |
| 25 | + (some? limit) (hsql/limit limit) |
23 | 26 | (some? order-by) (merge order-by) |
24 | 27 | (some? group-by) (merge group-by) |
25 | 28 | (seq category-ids) (-> (hsql/join [:event-categories :ec] [:= :events.id :ec.event-id]) |
26 | 29 | (hsql/where [:in :ec.category-id category-ids])))] |
27 | 30 | (hon/execute! |
28 | 31 | ds |
29 | | - (merge {:select [[[:count :*] :total]] |
30 | | - :from [:events]} |
| 32 | + (merge {:from [:events]} |
31 | 33 | clauses) |
32 | 34 | {:ret (if ret ret :*)}))) |
33 | 35 |
|
34 | 36 | (defn statistics-query |
35 | | - "returns the number of impressions, clicks and views, filtered by any other arguments accepted by metric-query" |
36 | | - [ds opts] |
| 37 | + "Returns the number of impressions, clicks and views, filtered by any other arguments accepted by metric-query. |
| 38 | + If ret is not given, returns a single record." |
| 39 | + [ds {:keys [ret] :as opts}] |
37 | 40 | (metric-query ds (merge {:select (hsql/select [(hsql/filter :%count.* (hsql/where := :event "impression")) :impressions] |
38 | 41 | [(hsql/filter :%count.* (hsql/where := :event "click")) :clicks] |
39 | 42 | [(hsql/filter :%count.* (hsql/where := :event "view")) :views]) |
40 | | - :ret :1} |
| 43 | + :ret (if ret ret :1)} |
41 | 44 | opts))) |
42 | 45 |
|
43 | 46 | (defn interval-statistics-query |
|
69 | 72 | :order-by (hsql/order-by column)} |
70 | 73 | opts)))) |
71 | 74 |
|
| 75 | +(defn top-statistics-query |
| 76 | + "Returns the top n of the given top field in order of the number of their impressions, clicks and views within the given time period" |
| 77 | + [ds min-date max-date n top-field opts] |
| 78 | + (metric-query ds (merge {:select (hsql/select top-field |
| 79 | + [(hsql/filter :%count.* (hsql/where := :event "impression")) :impressions] |
| 80 | + [(hsql/filter :%count.* (hsql/where := :event "click")) :clicks] |
| 81 | + [(hsql/filter :%count.* (hsql/where := :event "view")) :views]) |
| 82 | + :min-date min-date |
| 83 | + :max-date max-date |
| 84 | + :where (hsql/where [:!= top-field nil]) |
| 85 | + :group-by (hsql/group-by top-field) |
| 86 | + :order-by (hsql/order-by [:impressions :desc] [:clicks :desc] [:views :desc]) |
| 87 | + :limit n |
| 88 | + :ret :*} |
| 89 | + opts))) |
| 90 | + |
72 | 91 | (defn weekly-growth-averages |
73 | 92 | "Returns the percentage of growth in impressions, clicks and views per week, over the given time period. |
74 | | - Uses the first week as a basis for comparison, not included in results. |
| 93 | + Uses the first week as a basis for comparison. |
75 | 94 | Can be filtered by any other arguments accepted by metric-query." |
76 | 95 | [ds min-date max-date opts] |
77 | 96 | (let [weeks (interval-statistics-query ds :weekly min-date max-date opts) |
|
171 | 190 | :bundle-id bundle-id |
172 | 191 | :distributor-id (:user-id bundle)}) feeds) |
173 | 192 | events' (insert-event! ds {:data events |
174 | | - :ret :*})] |
| 193 | + :ret :*})] |
175 | 194 | (insert-feed-event-categories! ds events' feeds))) |
176 | 195 |
|
177 | 196 | (defn insert-post-impressions! |
|
189 | 208 | :bundle-id bundle-id |
190 | 209 | :distributor-id (:user-id bundle)}) posts) |
191 | 210 | events' (insert-event! ds {:data events |
192 | | - :ret :*})] |
| 211 | + :ret :*})] |
193 | 212 | (insert-post-event-categories! ds events' posts))) |
194 | 213 |
|
195 | 214 | (defn insert-feed-click! |
|
205 | 224 | :bundle-id bundle-id |
206 | 225 | :distributor-id (:user-id bundle)} |
207 | 226 | event' (insert-event! ds {:data event |
208 | | - :ret :*})] |
| 227 | + :ret :*})] |
209 | 228 | (insert-feed-event-categories! ds event' feed))) |
210 | 229 |
|
211 | 230 | (defn insert-post-click! |
|
222 | 241 | :bundle-id bundle-id |
223 | 242 | :distributor-id (:user-id bundle)} |
224 | 243 | event' (insert-event! ds {:data event |
225 | | - :ret :*})] |
| 244 | + :ret :*})] |
226 | 245 | (insert-post-event-categories! ds event' post))) |
227 | 246 |
|
228 | 247 | (defn insert-post-view! |
|
239 | 258 | :bundle-id bundle-id |
240 | 259 | :distributor-id (:user-id bundle)} |
241 | 260 | event' (insert-event! ds {:data event |
242 | | - :ret :*})] |
| 261 | + :ret :*})] |
243 | 262 | (insert-post-event-categories! ds event' post))) |
244 | 263 |
|
245 | 264 | (comment |
|
290 | 309 | (time (metric-query ds {:min-date "2025-11-25 15:00:00" |
291 | 310 | :feed-id "1"})) |
292 | 311 |
|
293 | | - (time (statistics-query ds {:content-type 1 |
294 | | - :creator-id 1 |
295 | | - :bundle-id 1 |
296 | | - :ret :1})) |
| 312 | + (time (statistics-query ds {:ret :*})) |
297 | 313 |
|
298 | 314 | (time (hon/find ds {:tname :events |
299 | 315 | :where [:< :id 500] |
|
304 | 320 | :data {:timestamp (str "2025-11-22" " 13:00:00")} |
305 | 321 | :ret :*})) |
306 | 322 |
|
307 | | - (time (hon/execute! ds (- (hsql/select [[:date :timestamp] :day] |
308 | | - [(hsql/filter :%count.* (hsql/where := :event "impression")) :impressions] |
309 | | - [(hsql/filter :%count.* (hsql/where := :event "click")) :clicks] |
310 | | - [(hsql/filter :%count.* (hsql/where := :event "view")) :views]) |
311 | | - (hsql/from :events) |
312 | | - (hsql/where [:between :timestamp "2025-11-17 00:00:00" "2025-11-24 23:59:59"]) |
313 | | - (hsql/group-by :day) |
314 | | - (hsql/order-by :day)) {:ret :*})) |
| 323 | + (time (hon/execute! ds (-> (hsql/select [[:date :timestamp] :day] |
| 324 | + [(hsql/filter :%count.* (hsql/where := :event "impression")) :impressions] |
| 325 | + [(hsql/filter :%count.* (hsql/where := :event "click")) :clicks] |
| 326 | + [(hsql/filter :%count.* (hsql/where := :event "view")) :views]) |
| 327 | + (hsql/from :events) |
| 328 | + (hsql/where [:between :timestamp "2025-11-17 00:00:00" "2025-11-24 23:59:59"]) |
| 329 | + (hsql/group-by :day) |
| 330 | + (hsql/order-by :day)) {:ret :*})) |
315 | 331 |
|
316 | 332 | (time (interval-statistics-query ds :daily "2025-11-17" "2025-11-24" {:feed-id 4})) |
317 | 333 |
|
|
356 | 372 | [(hsql/filter :%count.* (hsql/where := :event "view")) :views]))) |
357 | 373 |
|
358 | 374 | (time (insert-event! ds {:data {:timestamp (util/get-utc-timestamp-string) |
359 | | - :event "impression" |
360 | | - :feed-id 1 |
361 | | - :content-type-id 1 |
362 | | - :creator-id 1 |
363 | | - :bundle-id 1 |
364 | | - :distributor-id 1}})) |
| 375 | + :event "impression" |
| 376 | + :feed-id 1 |
| 377 | + :content-type-id 1 |
| 378 | + :creator-id 1 |
| 379 | + :bundle-id 1 |
| 380 | + :distributor-id 1}})) |
| 381 | + |
| 382 | + (time (top-statistics-query ds "2025-11-17" "2025-11-24" 10 :post-id {})) |
365 | 383 |
|
366 | 384 | ()) |
367 | 385 |
|
0 commit comments