Thank you very much Francis, that was very helpful :) On Thu, Jun 4, 2015 at 1:21 PM Francis Avila <fav...@breezeehr.com> wrote:
> (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. > -- 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.