2015-08-05 2 views
2

Я работаю с datomic.api для clojure. Я хочу реорганизовать несколько сложный запрос на регистрацию, например:Определение компонентов запроса данных за пределами (datomic.api/q '[])

(datomic.api/q '[:find [?value ...] :in $ ?uid ?component :where 
       [...some clause...] 
       [...some other clause...] 
       (or-join [?entitlement ?component] 
         (and [...some conditional stuff...]) 
         (and [...some other conditional stuff...]))] 
       db uid component) 

... во что-то более читаемое. Мое желание - локально связать компоненты запроса (and...) внутри let и обратиться к ним по имени внутри списка данных. Как так:

(datomic.api/q '[:find [?value ...] :in $ ?uid ?component :where 
       [...some clause...] 
       [...some other clause...] 
       (or-join [?entitlement ?component] 
         entitled-for-component 
         entitled-for-application)] 
       db uid component) 

Различные процитировать let (и unquoting внутри списка datomic.api/Q в) не работал. Какие-либо предложения?

+0

Да. Сортировка quoting/unquoting sort-of работает, если вы используете цитирование синтаксиса, но тогда вы получите такие вещи, как * и *, которые будут заменены символами с именами, которые будут отличаться от другого. Ниже приведен ваш ответ. –

+0

Мне нравится ответ ниже, чтобы использовать правила. Чтобы quasiquote в Clojure, как вы бы в других lisps, попробуйте форму 'template' в [backtick] (https://github.com/brandonbloom/backtick). –

ответ

2

Datomic использует rules для решения этой проблемы.

Datomic datalog позволяет вам упаковывать комплекты: where clauses в именованные правила. Эти правила делают повторную логику запросов, а также , что означает, что вы можете привязывать части логики запроса к времени запроса .

Набор правил определен как список списков, а затем используется как дополнительный вход с datomic.api/q, привязанным к символу%.

(def rules [[(name-for-id restaurant-id?) 
      [restaurant-id? :restaurant/name name?]]]) 

(datomic.api/q '[:find ?name . :in $ % ?restaurant-id :where 
       (name-for-id restaurant-id?)] db rules 42) 

=> "Milliways" 

Обратите внимание, что datomic.api/q ожидает правило набор, передавая одно правило не будет работать.

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

Кроме того,

Как и другие, где статьи, вы можете указать базу данных перед правилом имя- для определения области правил в этой базе данных. Базы данных не могут использоваться как аргументы в правиле.

Смежные вопросы