This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-14
Channels
- # beginners (31)
- # boot (9)
- # cider (10)
- # cljs-dev (9)
- # cljsrn (16)
- # clojure (222)
- # clojure-austin (4)
- # clojure-france (13)
- # clojure-italy (21)
- # clojure-nl (2)
- # clojure-russia (71)
- # clojure-spec (9)
- # clojure-uk (39)
- # clojurescript (50)
- # cursive (16)
- # datomic (69)
- # dirac (2)
- # figwheel (1)
- # graphql (19)
- # hoplon (4)
- # jobs (1)
- # klipse (3)
- # leiningen (4)
- # liberator (3)
- # luminus (9)
- # lumo (9)
- # off-topic (3)
- # om (21)
- # onyx (11)
- # parinfer (2)
- # pedestal (8)
- # planck (19)
- # re-frame (17)
- # reagent (12)
- # remote-jobs (1)
- # ring-swagger (3)
- # spacemacs (17)
- # specter (23)
- # sql (1)
- # unrepl (64)
- # untangled (19)
- # yada (5)
@devth they can't, and you can definitely benefit from the client itself having some notion of a tempid. Note than you can also use unique-identity attribute for upsert, e.g {:a/id "some-id" :a/b {:b/id "some other id"}}
instead of {:a/id "some-id" :a/b [:b/id "some other id"]}
Be careful of the security issues that can be caused by sending that from the client though
val_waeselynck: thanks. you mean client as in browser? in my case i'm sending them from the server side of a peer.
Yes as in browser
How would one query Datomic for any entities where attr1 has value a
OR attr2 has value b
? I can't use an or
clause because the attrs are different. I feel like I might be missing something simple here.
Not sure if this is the best solution, but you could always do two queries and combine the results afterwards.
@jeff.terrell Yeah. That's my fallback option. I'm just surprised that there is (apparently) no way to do this in one query.
@cap10morgan are you absolutely sure or clause is not what you need? i do use it with different attrs….. ??
it seems to me like it is is EXACTLY for that reason. on one attr you can have logical or by binding a collection
@karol.adamiec I got an error when I tried and the docs say: "All clauses used in an or clause must use the same set of variables, which will unify with the surrounding query. This includes both the arguments to nested expression clauses as well as any bindings made by nested function expressions."
ahh, yes
so the issue is in binding ;/
but maybe I'm doing it wrong 🙂
so OR claus works for :attr1 :attr2 only when it is bound to the same variable a
seems like two queries then 😞
@cap10morgan show us the clauses. You probably need or-join
ah, so maybe (or-join [?user] ...
?
hey, that seems to work. thanks @favila!
oh, huh. it looks like the or-join
version does not work. it finds every user b/c the ?email-search
and ?phone
vars don't get unified with their inputs I guess?
so the relation binding version might be the way to go
(d/q '{:find [[(pull ?user [*]) ...]]
:in [$ ?email-search ?phone]
:where [(or-join [?user ?email-search ?phone]
[?user :user/email-search ?email-search]
[?user :user/phone ?phone])]}
(d/db c) "" "+14055556666")
huh, I would have thought that was what it was doing w/o or-join
interesting
thanks again @favila
Now I'm wondering which one I prefer. Do you prefer the or-join
over the relation binding, @favila?
explicit or-join is the only thing you can do if you have to check more than one pattern to match a condition
or-join is probably also faster, since the query compiler can see what attrs it needs to look up
i.e., I had a set of different attributes I could match on, all attrs are on the same entity, and my searches could have one or many in any combination
yeah, makes sense. thanks!
Two uses:
- {:find [?name-e ?e] :where [[(ground (quote ?e)) ?name-e] ...(stuff)...]}
- To know the "name" of each match
- {:find [?e] :where [[(ground 12313) ?e] ...]}
- To force the match to occur in a specific entit(ies)
In general, these 2 uses at the same time. Queryies, with ground at begin of where
, are taking ~100ms on an "empty"(very small background), mem, db.
ground is supposed to take literals, so the value of ?name-e
is either (quote ?e)
(a list) or ?e
(a symbol)
I am interested in how you use it in (stuff)
because I can't think how that would work
but that is a legit use and I don't think any other way of getting ?e and its value at the same time would be faster
{:find [?e688269 ?e
?stage1688270 ?stage1
?stage2688271 ?stage2
?date-close688272 ?date-close
?date-open688273 ?date-open]
:where [[(ground 17592186046417) ?stage2]
[(ground #inst"2017-11-29T20:44:21.770-00:00") ?date-close] ;;**
[(ground (quote ?e)) ?e688269]
[(ground (quote ?stage1)) ?stage1688270]
[(ground (quote ?stage2)) ?stage2688271]
[(ground (quote ?date-close)) ?date-close688272]
[(ground (quote ?date-open)) ?date-open688273]
[?e :stage-container/calendar ?stage1]
[?e :stage-container/calendar ?stage2]
[?stage1 :calendar/stage-type :stage-type/a]
[?stage2 :calendar/stage-type :stage-type/b]
[?stage1 :calendar/close ?date-close]
[?stage2 :calendar/open ?date-open]]}
It's automatically generated....On ;;**
, it's auto generated basead on other query. I dont know what results are entities-id, what are values...
'{:find [?e
?stage1
?stage2
?date-close
?date-open]
:where [[(ground 17592186046417) ?stage2]
[(ground #inst"2017-11-29T20:44:21.770-00:00") ?date-close]
[?e :stage-container/calendar ?stage1]
[?e :stage-container/calendar ?stage2]
[?stage1 :calendar/stage-type :stage-type/a]
[?stage2 :calendar/stage-type :stage-type/b]
[?stage1 :calendar/close ?date-close]
[?stage2 :calendar/open ?date-open]]}
for exampleRemoving "label grounds", (dotimes [i 1000])
, goes from 3s to 2s.
A single query on repl, is 10x faster then "on integration test" 😕
I'm going it on a d/with
db-after ("on code")... But I think that should not be relevant..
[?e :stage-container/calendar ?stage2]
[?stage2 :calendar/stage-type :stage-type/b]
[?e :stage-container/calendar ?stage1]
[?stage1 :calendar/stage-type :stage-type/a]
[?stage1 :calendar/close ?date-close]
[?stage2 :calendar/open ?date-open]
writing it by hand I would do this. (I might reorder the clauses if I knew more about the schema):
'{:find [[(pull ?e [:db/id
{:stage-container/calendar
[:calendar/open
:calendar/close
{:calendar/stage-type [:db/ident]}]}]) ...]]
:in [$ ?stage2 ?date-close]
:where [[?stage2 :calendar/stage-type :stage-type/b]
[?stage1 :calendar/close ?date-close]
[?stage1 :calendar/stage-type :stage-type/a]
[?e :stage-container/calendar ?stage2]
[?e :stage-container/calendar ?stage1]]}
I’m trying to write a query that checks whether a condition is sufficient for the last 4 out of 7 days. any suggestions on how to structure the datalog?