This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-29
Channels
- # aws (6)
- # beginners (33)
- # bitcoin (2)
- # boot (22)
- # carry (2)
- # cider (5)
- # clara (21)
- # cljs-dev (115)
- # cljsrn (40)
- # clojure (161)
- # clojure-dev (73)
- # clojure-italy (38)
- # clojure-russia (88)
- # clojure-spec (123)
- # clojure-uk (58)
- # clojurescript (88)
- # core-async (26)
- # cursive (5)
- # datascript (18)
- # datomic (26)
- # hoplon (50)
- # java (2)
- # jobs (1)
- # leiningen (10)
- # lumo (1)
- # off-topic (18)
- # om (9)
- # onyx (26)
- # parinfer (13)
- # pedestal (41)
- # quil (1)
- # re-frame (27)
- # reagent (21)
- # ring-swagger (11)
- # slack-help (3)
- # spacemacs (8)
- # specter (5)
- # sql (42)
- # timbre (1)
- # uncomplicate (7)
- # untangled (3)
- # videos (1)
- # yada (26)
Hey guys. I want to query some data that is filtered by a value, but ONLY if that value is not nil. I currently have:
'[:find ?label ?value
:where
[?i :functiontype/functiontype ?label]
[?i :functiontype/functiontypeid ?value]
[?i :functiontype/blocked false]
[_ :offer/function ?fid]
[?j :functions/functionid ?fid]
[?j :functions/functiontypeid ?ftid]
[(or (nil? ?fid) (= ?ftid ?value))]]
but that doesn't seem to work, and also doesn't seem very idiomatic... Could anybody suggest an alternative?@linuss maybe you could use a disjunction? http://blog.datomic.com/2015/01/datalog-enhancements.html
@linuss there will never be a nil value in datomic. Instead use missing?
http://docs.datomic.com/query.html#sec-5-12-5
[(or (nil? ?fid) (= ?ftid ?value))]
is always true, because those inner items of or
are literal lists
you could have a top-level or
(or a rule) with two branches, one of which asserts value is nil, and this is the nil-case query, another one starts with [?i :functiontype/functiontypeid ?value]
and is the non-nil case
yes, but one branch will assert that ?value is nil, and the other one will match on nil, and both of these can't be true at the same time
@hmaurer eg
(defn query-with-optional-filters [name]
{:query {:find '[?e]
:in (cond-> '[$]
name (conj '?name))
:where
(cond-> '[[?e :foo :bar]]
name (conj '[?e :name ?name]))}})
@favila oh, so you build up the query dynamically based on the presence of a filter. Neat
Okay, so this is my new query:
[:find ?label ?value
:where
(or
(and [?i :functiontypes/functiontype ?label]
[?i :functiontypes/functiontypeid ?value]
[(missing $ ?e :offer/function)])
(and [_ offer/function ?fid]
[?i :function/functionid ?fid]
[?i :function/functiontypeid ?value]
[?j :functiontypes/functiontypeid ?value]
[?j :functiontypes/functiontype ?label]))]
but this won't run, saying Cannot parse clause, expected (data-pattern | pred-expr | fn-expr | rule-expr | not-clause | not-join-clause | or-clause | or-join-clause)