Search code examples
clojuredatomicdatalogdatascript

How to query against attributes of multiple values?


Tested on datascript 1.3.0

datoms:

[{:db/id -1 :name "Oliver Smith" :hobbies ["reading" "sports" "music"]}] 

tried to run the query below to find who like sports, but the empty set returned.

'[:find ?name
  :where
  [?p :name ?name]
  [?p :hobbies ?hobbies]
  [(some #{"sports"} ?hobbies)]] 

How to formulate the query correctly to get the expected result below?

#{[Oliver Smith]}

Solution

  • We have to explicitly define the schema with cardinality/many against the attribute of multiple values to solve the problem since schemaless doesn't work here.

    (require '[datascript.core :as d])
    
    (def schema {:hobbies {:db/cardinality db.cardinality/many}})
    (def conn (d/create-conn schema))
    
    (def datoms [{:db/id -1 :name "Oliver Smith" :hobbies ["reading" "sports" "music"]}])
    (d/transact! conn datoms)
    
    (def query '[:find ?name :where [?p :name ?name] [?p :hobbies "sports"]])
    (-> (d/q query @conn) println)