我正在使用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列表中的未引用内容)无效。有什么建议吗?
答案 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将规则范围限定为该数据库。无法使用数据库 作为规则中的论据。