This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-10-19
Channels
- # announcements (7)
- # aws (4)
- # aws-lambda (1)
- # babashka (19)
- # beginners (60)
- # calva (9)
- # chlorine-clover (3)
- # cider (15)
- # clj-kondo (17)
- # clojure (34)
- # clojure-czech (1)
- # clojure-europe (96)
- # clojure-nl (2)
- # clojure-uk (46)
- # clojurescript (20)
- # css (4)
- # cursive (58)
- # data-science (3)
- # datascript (3)
- # datomic (42)
- # depstar (30)
- # dirac (4)
- # emacs (1)
- # etaoin (5)
- # events (1)
- # figwheel-main (30)
- # fulcro (6)
- # helix (9)
- # jobs (1)
- # lumo (3)
- # malli (27)
- # off-topic (15)
- # pathom (11)
- # programming-beginners (6)
- # reitit (6)
- # rewrite-clj (11)
- # shadow-cljs (14)
- # sql (1)
- # tools-deps (18)
- # utah-clojurians (3)
can I write a shortest path query in Datomic, e.g can I determine if it is possible to navigate from Entity A to Entity B via some reference attribute?
'[[(path-exists? ?e1 ?a ?e2)
[?e1 ?a ?e2]]
[(path-exists? ?e1 ?a ?e2)
[?e1 ?a ?e-mid]
[(!= ?e2 ?e-mid)]
[(path-exists? ?e-mid ?a ?e2)]]]
the general pattern with recursive rules is to define the rule multiple times, and have one that is terminal, and the rest recursive, and (generally but not required) the rule impls match disjoint sets.
unfortunately there’s no “cut” to stop evaluation early. I’m pretty sure this example will exhaustively discover every possible path, even though any one will do. However, it may discover them in parallel.
Note this example only searches refs in a forward direction. With two additional implementations, it could search backwards also
I’ve looked at all the examples of recursive rules that I could find and they all “hardcode” the depth of the search (such as the MBrainz example: https://github.com/Datomic/mbrainz-sample/blob/master/src/clj/datomic/samples/mbrainz/rules.clj#L37)
I would've expected the below query to return all txes where ?tx is not in ?ignore-tx. I actually get all txes, as if the not
is completely ignore. ?ignore-tx is passed in as a set of tx ids. Why would this happen?
'[:find ?t ?status ?tx ?added
:in $ [?ignore-tx ...]
:where
[?t ::task/status ?status ?tx ?added]
(not [(identity ?ignore-tx) ?tx])]
datalog comparisons are not “type”-aware. are all ?ignore-tx actually tx longs and not some other representation?
and you’re actually sure this is in the result set? You can test with `
'[:find ?t ?status ?tx ?added
:in $ [?tx ...]
:where
[?t ::task/status ?status ?tx ?added]
]
(d/q {:query '[:find ?t ?status ?tx ?added
:in $ [?ignore-tx ...]
:where
[?t ::task/status ?status ?tx ?added]
[(!= ?ignore-tx ?tx)]
[?tx :audit/user-id ?user]]
:args [(d/history (d/db conn))
#{13194142035321 13194142112981}]
:limit 10000})
=>
[[606930421025569 :cs.model.task/status-in-progress 13194142112981 false]
[606930421025569 :cs.model.task/status-in-progress 13194142035321 true]
[606930421025569 :cs.model.task/status-open 13194142112981 true]
[606930421025569 :cs.model.task/status-open 13194142035321 false]]
(d/q '[:find ?e ?stat ?tx ?op
:in $ [?ignore-tx ...]
:where
[?e :status ?stat ?tx ?op]
[(!= ?ignore-tx ?tx)]
]
[[1 :status :foo 100 true]
[1 :status :bar 100 false]]
#{100}
)
(d/q '[:find ?e ?stat ?tx ?op
:in $ ?ignore-txs
:where
[?e :status ?stat ?tx ?op]
(not [(contains? ?ignore-txs ?tx)])
]
[[1 :status :foo 13194142112981 true]
[1 :status :bar 13194142112981 false]
[1 :status :baz 13194142112982 true]]
#{13194142112981}
)
=> #{[1 :baz 13194142112982 true]}
I’m just kinda probing to see if this is a problem with comparisons or something deeper
(d/q {:query '[:find ?t ?status ?tx ?added
:in $ ?ignore-tx
:where
[?t ::task/status ?status ?tx ?added]
(not [(contains? ?ignore-tx ?tx)])
[?tx :audit/user-id ?user]]
:args [(d/history (d/db conn))
#{13194142035321 13194142112981}]})
=> []
I think that points to something funky with the numeric comparisons done by the datalog engine, like it’s using object identity or something.
my toy example used on-prem, but should be able to replicate with cloud or peer-server
Datomic Cloud includes :db-name
and :database-id
as get
'able keys from a d/db
. Are these part of the official API?
e.g.,
(d/db conn)
=>
{:t 2580397,
:next-t 2580398,
:db-name "my-db",
:database-id "74353541-feea-4ea2-afa6-f522a169856d",
:type :datomic.client/db}
It would appear so (for :db-name at least) https://docs.datomic.com/client-api/datomic.client.api.html#var-db
If that is true, shouldn't dev-local support that? See below example using dev-local 0.9.203.
(def c2 (d/client {:server-type :dev-local,
:system "dev-local-bB7z07Io_A",
:storage-dir "/home/kenny/.datomic/data/dev-local-bB7z07Io_A"}))
(d/db (d/connect c2 {:db-name "cust-db__0535019e-79fe-44a1-a8d9-b19394abd958"}))
(:db-name *1)
=> nil
Fairly certain this is a bug so I opened a support req: https://support.cognitect.com/hc/en-us/requests/2879