在(datomic.api / q'[])之外定义数据记录查询组件

时间:2015-08-05 17:21:08

标签: clojure datomic datalog

我正在使用clojure的datomic.api。我希望重构一个有点复杂的数据记录查询,例如:

(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中的各种引用(以及datomic.api / q列表中的未引用内容)无效。有什么建议吗?

1 个答案:

答案 0 :(得分:2)

Datomic使用rules来解决此问题。

  

Datomic数据记录允许您打包以下各项:where子句   命名规则。这些规则使查询逻辑可重用,而且   可组合的,这意味着您可以绑定查询逻辑的部分   查询时间。

规则集被定义为列表列表,然后用作绑定到%字符的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期望规则设置,传递单个规则将无效。

规则中的第一个列表将规则名称定义为第一个项目,后跟一个或多个参数。后续向量包含一个或多个:where子句。

此外,

  

与其他where子句一样,您可以在之前指定数据库   rule-name将规则范围限定为该数据库。无法使用数据库   作为规则中的论据。