我正在使用 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/