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

标签 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)

...变成更具可读性的东西。我的愿望是在 let 中本地绑定(bind)查询的 (and...) 组件,并通过数据日志列表中的名称引用它们。就像这样:

(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 使用 rules来解决这个问题。

Datomic datalog allows you to package up sets of :where clauses into named rules. These rules make query logic reusable, and also composable, meaning that you can bind portions of a query's logic at query time.

规则集被定义为列表的列表,然后用作附加输入,datomic.api/q 绑定(bind)到 % 字符。

(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 子句。

另外,

As with other where clauses, you may specify a database before the rule-name to scope the rule to that database. Databases cannot be used as arguments in a rule.

关于clojure - 在 (datomic.api/q '[]) 之外定义数据记录查询组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31838952/

相关文章:

java - 如何在 Datomic 查询中使用/?

collections - 在 clojure 中使用 'map' 和不同大小的集合

datomic - 用基数更新值很多

clojure - 通过带有 Datomic 和 GPG key 的 SSH 使用 "lein ring server"

clojure - 在结果元组中检索实体 ID 时,Datomic 未返回正确的 "min"结果

clojure - Datomic:如何在查询中跨任意数量的数据库进行查询?

clojure - Compojure - 使用重定向时避免 "manual"URL 格式

clojure - 我的简单 Clojure gen-class 脚本有什么问题?

clojure - 如何使用 if-let 中的嵌套 let 编写一次函数调用?