2

我正在使用 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...)查询的组件本地绑定到 alet中,并通过数据日志列表中的名称来引用它们。像这样:

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

letdatomic.api/q 列表中的各种引用(和取消引用)都不起作用。有什么建议么?

4

1 回答 1

2

Datomic 使用规则来解决这个问题。

Datomic datalog 允许您将 :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 子句一样,您可以在规则名称之前指定一个数据库,以将规则范围限定为该数据库。数据库不能用作规则中的参数。

于 2015-08-05T17:45:34.467 回答