1

应用

我想以编程方式生成以下形式的查询。

(q '[:find ?id ?val1 ?val2 ?val3 ?val4 ...
     :where [?x :id ?id] 
            [?x :attr1 ?val1]
            [?x :attr2 ?val2]
            [?x :attr3 ?val3]
            [?x :attr4 ?val4]
            ....]
     (db conn))

这些是收集一组预定义属性的相当标准的查询。

当前解决方案

我能做的最好的就是使用:in如下

(q '[:find ?id ?val
     :in  $ [?attr ...]
     :where [?x :id ?id] 
            [?x ?attr ?val]]
     (db conn) [:attr1 :attr2 :attr3 :attr4])

但这为我提供了n每个实体的一组事实。真的我想收到一组长度向量,n+1其中n是指定属性的数量。我还希望元素的顺序能够反映给定属性的顺序。

程序化生成

因为 Datomic 查询是数据结构,所以我应该能够以编程方式生成它们。我发现这很困难有几个原因,这两个原因都源于我对宏的不熟悉

  1. 我怎样才能创建像?val1. 我可以映射?到一堆生成的字符串吗?

    (map ? value-strings)

  2. 领导'吓到我了。这不会阻止我的自动化代码运行,直到?x处理完元素之后?

或者,有没有更惯用的解决方案?

4

1 回答 1

6

更新...

正如@TomJack 所写,Datomic 支持另一种基于地图的语法,这将使您的查询更容易。

(let [attributes [:name :height :weight :age]
      valnames (map #(symbol (str "?" (name %))) attributes)
      x-terms (map #(vector '?x %1 %2) attributes valnames)
      query {:find valnames
             :where (cons ['?x :id '?id] x-terms)}]
  (q query (db conn)))
于 2013-08-01T13:50:15.450 回答