Fork me on GitHub
#datascript
<
2017-06-29
>
linuss12:06:23

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?

misha12:06:00

@linuss do you want all non-nil? or some exact match and nil?

misha12:06:44

I see, wait

linuss12:06:48

ah okay 🙂

misha12:06:50

you need to use missing?

misha12:06:34

(let [rules '[[(exact-or-missing ?e ?a ?v) [?e ?a ?v]]
              [(exact-or-missing ?e ?a ?v) (missing? ?e ?a)]]]
  (ds/q
    '[:find ?label ?value
      :in $ %  ;; % is a reserved symbol for passing in rules
      :where
      [?i :functiontype/functiontype ?label]
      [?i :functiontype/functiontypeid ?value]
      [?i :functiontype/blocked false]
      [_ :offer/function ?fid]
      [?j :functions/functionid ?fid]
      (exact-or-missing ?j :functions/functiontypeid ?value)]
    @conn rules))

misha12:06:24

rules is a workaround for or

linuss12:06:22

Let me try that!

linuss12:06:05

Hmm. I'm afraid that returns nothing if there is no :offer/function

misha12:06:29

of course

misha12:06:17

every clause has to be true to return any search results

linuss12:06:19

ah, right. Okay, my question was if it were possible (within one query) to filter if and only if :offer/function wasn't nil

linuss13:06:15

Okay, I got some tips from the folks over at #datomic, and came up with this:

[: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]))]
This however results in the error Cannot parse clause, expected (data-pattern | pred-expr | fn-expr | rule-expr | not-clause | not-join-clause | or-clause | or-join-clause). Can anybody spot my mistake?

misha14:06:13

and is implicit. everything is inside huge and

misha14:06:37

or is not supported in datascript