Find entity with most occurrences in a relation in Datomic

188 views Asked by At

Is there a way to express this kind of logic purely inside a query?

(def e-top
  (let [res (d/q '[:find ?e (count ?p)
                   :where [?p :likes ?e]] db)]
    (first (apply max-key last res))))
1

There are 1 answers

0
Ben Kamphaus On BEST ANSWER

If you need to work within one query, then aggregate of aggregates problems are best tackled with subquery (a nested call to query inside query). See this answer on the Datomic mailing list which includes a similar (not identical) query on the results of an aggregate against mbrainz:

(d/q '[:find ?track ?count
       :where [(datomic.api/q '[:find ?track (count ?artist)
               :where [?track :track/artists ?artist]] $) [[?track ?count]]]
       [(> ?count 1)]]
  (d/db conn))

For your case (assuming work stays in Clojure), apply will be faster and simpler. Subqueries that only need to do something simple (e.g. get something associated with the max value) tend to make more sense if you're using the REST API or some other client wrapping around Datomic where you don't have the perf benefits associated with the Peer library being in process.