Clojure 在(datomic.api/q';[])之外定义数据日志查询组件

Clojure 在(datomic.api/q';[])之外定义数据日志查询组件,clojure,datomic,datalog,Clojure,Datomic,Datalog,我正在使用clojure的datomic.api。我希望重构一个有点复杂的数据日志查询,如下所示: (datomic.api/q '[:find [?value ...] :in $ ?uid ?component :where [...some clause...] [...some other clause...] (or-join [?entitlement ?component]

我正在使用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)
…变成更具可读性的东西。我的愿望是在
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列表中的取消引用)都不起作用。有什么建议吗?

Datomic用于解决此问题

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子句一样,可以在 规则名称,将规则的作用域设置为该数据库。无法使用数据库 作为规则中的参数


是的。如果使用语法引号,引号/取消引号的方法会起作用,但最终会出现和被命名空间限定的符号所取代,这将以一种更不同的方式打破它。下面是你的答案。我喜欢下面的答案,使用规则。要像在其他Lisp中一样在Clojure中使用Quasikote,请尝试中的
模板
表单。