Peter
Peter

Reputation: 48978

Parameterized and case insensitive query in datalog (datomic)

I want to compose a query that takes a firstname as input parameter and returns all matching records. A match should be case insensitive. As an example I'd like to extract all the people named Douglass. Parameterized, but case sensitive this would be :

(d/q '[:find (pull ?e [*])
       :in $ ?par
       :where
       [?e :person/firstname ?par]
       ] db "Douglass")

The following query will yield all matches regardless the case, but is not parameterized (the ?par is not used yet, but a placeholder for the parameterized query) :

(d/q '[:find (pull ?e [*])
       :in $ ?par
       :where
       [?e :person/firstname ?bfn]
       [(re-find (re-pattern "(?i)DouGLASS") ?bfn)]
       ] db "")

But I'm not able to combine them. A - probably naive - approach is throwing Unable to resolve symbol: ?par in this context :

(d/q '[:find (pull ?e [*])
       :in $ ?par
       :where
       [?e :person/firstname ?bfn]
       [ (re-find (re-pattern (str "(?i)" ?par)) ?bfn)]
       ] db "Douglass")

So : how to pass the firstname for this case?

Upvotes: 3

Views: 694

Answers (1)

Ben Kamphaus
Ben Kamphaus

Reputation: 1665

As described here, the issue is that function expressions in Datomic Datalog do not nest. You could break it out like this (using a tested query against the mbrainz database).

(d/q '[:find ?name ?year
       :in $ ?match
       :where [(str "(?i)" ?match) ?matcher]
              [(re-pattern ?matcher) ?regex]
              [(re-find ?regex ?aname)]
              [?a :artist/name ?aname]
              [?r :release/artists ?a]
              [?r :release/name ?name]
              [?r :release/year ?year]]
     (d/db conn) "pink floyd")

Returns:

#{["Point Me at the Sky" 1972]
  ["Any Colour You Like" 1972]
  ["The Dark Side of the Moon" 1973]
  ["Obscured by Clouds" 1972]
  ...

You could also write your own function and call it from Datalog.

Upvotes: 1

Related Questions