(This question is more appropriate to the datomic group: https://groups.google.com/forum/#!forum/datomic)
Datomic/datalog queries always perform aggregation as a last step so the results of aggregation are unavailable to the :where clause. In other words, what you want is impossible with a single datalog query. However, this isn't SQL: the datalog query is run in the peer and all the data used for aggregation is transmitted to the peer anyway. Just filter over the results yourself with normal Clojure code. There's no advantage to expressing everything in a single query like there is in SQL. (let [db [[:t1 :track/name "foo"] [:l1 :lesson/track :t1] [:t2 :track/name "bar"] [:l2 :lesson/track :t2] [:t3 :track/name "baz"] [:l3 :lesson/track :t3] [:l4 :lesson/track :t3]]] (->> (d/q '[:find ?track (count ?lessons) :where [?t :track/name ?track] [?lessons :lesson/track ?t]] db) (filter (fn [[_ cnt]] (> cnt 1))))) ;=> (["baz" 2]) You can also use two queries: one to get the count per track, another to get the track names (but a simple filter is less verbose): (let [db [[:t1 :track/name "foo"] [:l1 :lesson/track :t1] [:t2 :track/name "bar"] [:l2 :lesson/track :t2] [:t3 :track/name "baz"] [:l3 :lesson/track :t3] [:l4 :lesson/track :t3]]] (->> (d/q '[:find ?t (count ?lessons) :where [?lessons :lesson/track ?t]] db) (d/q '[:find ?track ?num-lessons :in $ [[?t ?num-lessons]] :where [(> ?num-lessons 1)] [?t :track/name ?track]] db))) ;=> #{["baz" 2]} As a side note, be aware that if your track names are not unique you may get unexpected results from your current query: (let [db [[:t1 :track/name "foo"] [:l1 :lesson/track :t1] [:t2 :track/name "bar"] [:l2 :lesson/track :t2] [:t3 :track/name "foo"] [:l3 :lesson/track :t3] [:l4 :lesson/track :t3]]] (d/q '[:find ?track (count ?lessons) :where [?t :track/name ?track] [?lessons :lesson/track ?t]] db)) ;=> [["bar" 1] ["foo" 3]] This is because the aggregation is done over an unaggregated result *set* (i.e. all unique values) and ?track is the same for multiple ?t. The solution is to either include ?t in the :find, or use :with. See the Datomic docs more more details: http://docs.datomic.com/query.html#sec-5-17 On Thursday, June 4, 2015 at 6:35:08 AM UTC-5, Wilker wrote: > Hi, good morning. > > I have this query here: > > [:find ?track (count ?lessons) > :where > [?t :track/name ?track] > [?lessons :lesson/track ?t] > ] > > A lesson has a track (so a track can be on multiple lessons), and with > this query I can return the track names and the number of lessons where > this track is being used, all good here. > > But I would like to use this count information to filter, and return only > tracks that are present in more than one lesson, I tried: > > [:find ?track (count ?lessons) > :where > [?t :track/name ?track] > [?lessons :lesson/track ?t] > [(> (count ?lessons) 1)] > ] > > Also tried: > > [:find ?track ?lc > :where > [?t :track/name ?track] > [?lessons :lesson/track ?t] > [(count ?lessons) ?lc] > [(> ?lc 1)] > ] > > But I feel like I'm going on the wrong direction... How can I make this > query works? > > Thanks. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.