Fork me on GitHub
#datomic
<
2024-04-01
>
jjttjj00:04:57

Is there a way to express this in a query: How to find all labels for which ::value is > 100 OR ::key is a member of a set we provide. if we don't provide any keys, just use the > 100 predicate only. [I know this minimal example I could just use e.g. d/datoms but in the "real" example I'm attempting there's more joining going on where putting it all in one query would be convenient.]

(d/transact conn1
   {:tx-data
    [{:db/ident       ::key
      :db/valueType   :db.type/keyword
      :db/cardinality :db.cardinality/one}

     {:db/ident       ::value
      :db/valueType   :db.type/long
      :db/cardinality :db.cardinality/one}

     {:db/ident       ::label
      :db/valueType   :db.type/string
      :db/cardinality :db.cardinality/one}]})

 (d/transact conn1
   {:tx-data
    [{::key    :a
      ::label "a"
      ::value 101}

     {::key    :b
      ::label "b"
      ::value 50}

     {::key    :c
      ::label "c"
      ::value 50}
     ]})

 (d/q
   '[:find ?label
     :in $ [?provided ...]
     :where
     [?e ::label ?label]
     (or-join [?e ?provided]
       (and [?e ::value ?value]
            [(> ?value 100)])
       [?e ::key ?provided])
     ]
   (d/db conn1)
   [:b])
 ;; Works if we provide some keys
 ;;=>  [["a"] ["b"]]

 (d/q
   '[:find ?label
     :in $ [?provided ...]
     :where
     [?e ::label ?label]
     (or-join [?e ?provided]
       (and [?e ::value ?value]
            [(> ?value 100)])
       [?e ::key ?provided])
     ]
   (d/db conn1)
   [])
 ;; But returns nothing if we provide no keys
 ;; []

favila00:04:00

You need to destructure provided values inside the branch of the or-join about keys

jjttjj01:04:49

an, thanks again! This works perfectly (using identity)

(d/q
   '[:find ?label
     :in $ ?provided
     :where
     [?e ::label ?label]
     (or-join [?e ?provided]
       (and [?e ::value ?value]
            [(> ?value 100)])
       (and [(identity ?provided) [?p ...]]
            [?e ::key ?p]))
     ]
   (d/db conn1)
   [])