Search code examples
clojuredatomicdatalog

Datomic query: find all entities with some value


With this query:

{:find  [?e]
         :where [[?e :db/valueType :db.type/string]]}

I can find all entities with property named :db/valueType and value of :db.type/string. In my case with some data in the database it returns ten IDs.

How would I search for all entities with value of :db.type/string, regardless of the property name? For example this query:

{:find  [?e]
         :where [[?e _ :db.type/string]]}

returns an empty set. As far as I can understand Datomic's Datalog, _ should work as a wildcard, matching anything, so the second query should at least return the same number of results as the first one, and maybe even more than that.

Thanks...


Solution

  • For this example, the logical structure of the query is essentially correct, but the attribute ident keyword is not being resolved to its entity id. Note that this is a special case that occurs when you query with attributes as inputs - a scenario in which the query engine is not guaranteed to perform this conversion. See the Datomic docs on query (http://docs.datomic.com/query.html) for "Attributes as Query Inputs."

    A way to restructure this query is as:

        (let [db (d/db conn)] 
                (d/q '[:find ?e 
                       :in $ ?id 
                       :where [?e _ ?id]] 
                 db (d/entid db :db.type/string)))
    

    In this case, we resolve the keyword :db.type/string to its entity id manually in the input to the parameterized query.