"String name of the collection (i.e., `Table`) that we're currently querying against."
nil)
(def^:dynamic*constraints*
"Monger clauses generated from query dict `filter` clauses; bound dynamically so we can insert these as appropriate for various types of aggregations."
;; Unfortunately trying to do a MongoDB distinct aggregation runs out of memory if there are more than a few thousand values
;; because Monger currently doesn't expose any way to enable allowDiskUse in aggregations
;; (see https://groups.google.com/forum/#!searchin/clojure-mongodb/$2BallowDiskUse/clojure-mongodb/3qT34rZSFwQ/tYCxj5coo8gJ).
;;
;; We also can't effectively limit the number of values considered in the aggregation meaning simple things like determining categories
;; in sync (which only needs to know if distinct count is < 40, meaning it can theoretically stop as soon as it sees the 40th value)
;; will still barf on large columns.
;;
;; It's faster and better-behaved to just implement this logic in Clojure-land for the time being.
;; Since it's lazy we can handle large data sets (I've ran this successfully over 500,000+ document collections w/o issue).
[{:count(let[values(transient(set[]))
limit(:limit(:query*query*))
keep-taking?(iflimit(fn[_]
(<(countvalues)limit))
(constantlytrue))
field-id(or(:field-idfield); Field
(:field-id(:fieldfield)))]; DateTimeField
(->>(i/field-values-lazy-seq@(ns-resolve'metabase.driver.mongo'driver)(sel:onefield/Field:idfield-id)); resolve driver at runtime to avoid circular deps
(filteridentity)
(maphash)
(map#(conj!values%))
(take-whilekeep-taking?)
dorun)
(countvalues))}])
(defn-aggregation:sum[field]
(aggregate{$group{"_id"nil; TODO - I don't think this works for _id