datascript

Immutable database and Datalog query engine for Clojure, ClojureScript and JS
2019-03-13T18:49:48.009400Z

Let’s say I have datoms like this:

[{:edge/y 60 :db/id 1}
 {:edge/x 20 :db/id 2}
 {:edge/x 60 :db/id 3}
 {:edge/y 0 :db/id 4}]

2019-03-13T18:51:13.010Z

And I want to merge edges all the edges that have the same y or the same x.

2019-03-13T18:51:29.010400Z

What’s the best way to express that as a query and transaction?

2019-03-13T18:56:54.011300Z

Also, there are entities that reference those db/id’s, so I need to replace those references with whatever the result is.

2019-03-13T19:04:13.012Z

My first attempt is just pulling every edge:

'[:find ?id2 ?x
   :in $
  :where [?id1 :edge/x ?x]
  [?id2 :edge/x ?x]]

2019-03-13T19:14:02.012800Z

This query finds the right edges, but is more verbose than I expected:

'[:find ?id2 ?x1
                       :in $
                       :where
                       [?id1 :edge/x ?x1]
                       [?id2 :edge/x ?x2]
                       [(= ?x1 ?x2)]
                       [(!= ?id1 ?id2)]]

2019-03-13T20:08:22.013300Z

For the curious, this is where I’m landing for now:

(d/q '[:find ?id2 ?a ?v
                       :in $ [?id1 ...]
                       :where
                       [?id1 ?a ?v]
                       [?id2 ?a ?v]
                       [(!= ?id1 ?id2)]] @conn ids)

2019-03-13T20:10:12.015100Z

Even as a total novice, the Datalog way of doing things is soooooo nice for this stuff. It feels like the engine is doing all the code for me. Great work, all the contributors!