Параметризованный и нечувствительный к регистру запрос в журнале данных (datomic)

Я хочу составить запрос, который принимает имя в качестве входного параметра и возвращает все соответствующие записи. Соответствие должно быть без учета регистра. В качестве примера я хотел бы выделить всех людей по имени Дуглас. Параметризованный, но с учетом регистра это будет:

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

Следующий запрос выдаст все совпадения независимо от случая, но не параметризован (параметр? Par еще не используется, но заполнитель для параметризованного запроса):

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

Но я не могу их объединить. A - вероятно, наивный - подход бросает 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")

Итак: как передать имя для этого случая?

1 ответ

Решение

Как описано здесь, проблема заключается в том, что функциональные выражения в Datomic Datalog не вложены. Вы можете разбить его так (используя проверенный запрос к базе данных mbrainz).

(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")

Возвращает:

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

Вы также можете написать свою собственную функцию и вызвать ее из Datalog.

Другие вопросы по тегам