2012-09-18 7 views
6

私はREST APIを介してDatomicで '外部結合'を実行しようとしています。datomicクエリでデータベース関数を使用する

[:find ?n ?v :in $ :where [?e ?a ?v] [?a :db/ident :db/fn] [?e :db/ident ?n]] 

戻り

:maybe #db/fn{:code "(seq (map :a (d/datoms db :eavt e attr)))", :params [db e attr], :requires [], :imports [], :lang :clojure} 

をしかし、私は:私は多分、私のデータベースに機能し、そしてそれは、このように照会することができ、挿入

(defn maybe 
    "Returns the set of attr for e, or nil if e does not possess 
    any values for attr." 
    [db e attr] 
    (seq (map :a (d/datoms db :eavt e attr)))) 

;; find all users 
(q '[:find ?e ?upvote 
    :where 
    [?e :user/email] 
    [(user/maybe $ ?e :user/upVotes) ?upvote]] 
    (db conn)) 

https://github.com/Datomic/day-of-datomic/blob/master/tutorial/social_news.cljから私は最後の例をとっていますクエリで関数を呼び出す方法を理解できません。いくつかのトランザクションには:data/user属性があります。この属性は、存在する場所の値を取得したいものです。実行しようとしているクエリは次のとおりです。私は:maybeを上記で定義したデータベース関数にしたいと思います。

[:find ?attr ?v ?when ?who :where 
[17592186045423 ?a ?v ?tx true] 
[?a :db/ident ?attr] 
[(:maybe $ ?tx :data/user) ?who] 
[?tx :db/txInstant ?when]] 

私はかなり何かを明らかに欠けているかなり確信しているが、私は今の日のために、この上で立ち往生してきました。助けてくれてありがとう!

答えて

4

d/invokeを使用する必要があります。あなたの例は次のようになります:

[:find ?attr ?v ?when ?who :where 
[17592186045423 ?a ?v ?tx true] 
[?a :db/ident ?attr] 
[(d/invoke $ :maybe ?tx :data/user) ?who] 
[?tx :db/txInstant ?when]] 
+0

もちろん、d/invokeを呼び出すデータベース以外の関数を定義し、単にクエリ内から呼び出すこともできます。あなたが良い名前を選ぶと、クエリをより読みやすくするかもしれません。 – Brian

4

DatomicのQuery Docによれば、クエリでは純関数を使用できます。最初にインストールする必要はありません。インストールする必要のある関数は、トランザクション関数です。

クエリ関数は、他のすべての関数と同様にアプリケーションで実行されるため、インストールする必要はありません。 Datomicには、クエリを実行するデータベースサーバのようなものはありません。クエリは常にアプリケーション内でPeer Libraryによって実行されます。

インストールする必要がある唯一のタイプの機能は、Transactorの内部で実行されるため、トランザクション機能です。 Transactorは、Datomicのすべての書き込みを処理する単一の特殊なプロセスです。

+0

これは超クールです。これは新しいリンクhttp://docs.datomic.com/database-functions.htmlです。悲しいことにファーストクラスの関数はJava/Clojureは排他的です。 – est

関連する問題