2013-01-07 10 views
20

「組み込み」セクションは述べています:SQLのようなDatomicエンティティからすべてのフィールドを取得

クエリ言語は、単一conversatonに、あなたが行っている、クライアントサーバーモデル の周りに配向されています両方ともに:

  • あなたの基本的な質問に答えてください今月は靴下を買いました。
  • レポートや処理に必要な追加情報を復元します。彼らの名前と電子メールアドレスは何ですか?

後者は実際にはクエリではなく、単に機械的なナビゲーション 関連情報です。

2つの異なる側面の直交性がどのように受け入れられているかを理解していますが、多くの場合、その属性がどれであってもエンティティ全体を取得する必要があります。

私の知る限りでは、クエリは、通常、この形式を持つ:

(datomic.api/q '[:find ?name ?age ?email 
       :where 
       [?e :myapp/name ?name] 
       [?e :myapp/age ?age] 
       [?e :myapp/email ?email]] 
       (db conn)) 

私はNの属性を持っているエンティティを検索したい場合は、私は退屈思われ、各クエリでそれらをすべてリストアップするためにそれらを持っていると思いますエラーが発生する可能性があります。

明示的に指定することなく、永続化されたすべてのフィールドを持つエンティティを取得するようにDatomicに指示する方法を教えてください。

答えて

7

datomic.api/entityは、このような機能を提供します。

返されたマップには、:db/id以外のすべてのフィールドを非表示にするカスタム表現があります。これらのフィールドにはアクセスできますが、それらのフィールドを印刷するには、マップを通常のClojureマップにマージする必要があります。

+2

カップルのノートは:(1)実体がありません「隠す」属性は、エンティティ属性や関連するエンティティを取得するための怠惰なインターフェイスです。これはパフォーマンスの観点から理解する上で重要です。なぜなら、属性がすべてすぐには見えない理由を説明しています。属性を表示して怠惰の利点を打ち負かすためには、DBからデータムをフェッチする必要があります。 (2)エンティティをマップにマージする必要はありません。すべての属性を取得するには、[touch](http://docs.datomic.com/clojure/#datomic.api/touch)関数を呼び出します。 – camdez

1

私はそれをテストしていませんが、私の記憶が正しければ、あなただけの属性名

(datomic.api/q '[:find ?key ?value 
      :where 
      [?e ?key ?value]] 
      (db conn)) 
+0

クエリが単なるスタブであるかどうかは不明ですが、完全なデータベーススキャンが発生するためIllegalArgumentExceptionがスローされます – vemv

+0

はい、通常、意味のあるwhere句を追加することでエンティティを制限します。たとえば、[?e:user/name "Joe "] –

16

のようなクエリからエンティティ(ID)を持つものとして変数を置くことができます。

=> (def eid (d/q '[:find ?e :where [?e :myapp/name "Fred"]] (db conn))) 

あなたはEntityMapを取得することができます:

=> (def ent (d/entity (db conn) (ffirst eid))) 

ので、あなたは追加のqを行わずにフィールド/属性にアクセスすることができますueryで:

=> (seq ent) 
;; ([:myapp/name "Fred"] [:myapp/age 16] [:myapp/email "[email protected]"]) 

しかし、それは最初のキーを入手しやすくなることがあります。あなたも、キーを逆に取得することができます

=> (keys ent) 
;; (:myapp/name :myapp/age :myapp/email) 

以下のトリックを使用して(「外来」refは、このエンティティにそのポイントを属性):

=> (.touch ent) 
=> (keys (.cache ent)) 
+1

答えにコードサンプルを提供してくれてありがとう! –

+1

エンティティのキ​​ーが機能しません。 seqが動作します。 – haijin

7

datomic.api/touch機能

特定がありますはただちにに機能します。は、エンティティのすべての属性をタッチします。 Entityentity関数によって返され、アクセス時にのみ属性値が返され、touch関数はすべてのエンティティ属性を熱心に取得します。

例:

(let [entity (d/entity db-val (ffirst (d/q '[:find ?e :in $ ?email 
              :where [?e :user/email ?email]] 
              db-val email))] 
    ;;then just d/touch the entity returned by the d/entity fn 
    (d/touch entity)) 
=> {:user/username "gretchen", :user/email "[email protected]", :user/password "xxxxxx", :db/id 17592186046433} 
6

あなたは、エンティティ、あるいは単に選択からすべてのフィールドを取得するためにpullを使用することができます。プルのパターンとして'[*]を使用すると、すべてのフィールドが取得されます

the pull documentationと説明を参照してください。

ID eid使用してエンティティからすべてのフィールドを取得するには:

(d/pull (db conn) '[*] eid)

プルはクエリでも使用することができます:

(datomic.api/q '[:find (pull ?e [*]) 
       :where 
       [?e :myapp/name] 
       (db conn)) 
+0

':where'節の最後の位置で' _'を使う必要はありません。その位置は単に省略することができます。私は、 '[?e:myapp/name]'です。 –

関連する問題