28

Datomic QueriesandRulesドキュメントの「Embedded」セクションには次のように書かれています。

SQLのようなクエリ言語は、クライアントサーバーモデルを中心に据えられており、1回の会話で、次の両方を行う必要があります。

  • 今月靴下を購入した人など、基本的な質問に答えてください。
  • 名前や電子メールアドレスなど、レポートと処理に必要な追加情報を回復します。

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

言及された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に指示するにはどうすればよいですか?

4

5 に答える 5

20

次のようなクエリからエンティティ(id)を取得します。

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

EntityMapを取得できます。

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

したがって、追加のクエリを実行せずにフィールド/属性にアクセスできます。

=> (seq ent)
;; ([:myapp/name "Fred"] [:myapp/age 16] [:myapp/email "fred@email.com"])

ただし、最初にキーを取得する方が簡単な場合があります。

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

次のトリックを使用して、リバースキー(このエンティティを指す「外部」ref属性)を取得することもできます。

=> (.touch ent)
=> (keys (.cache ent))
于 2013-04-15T21:42:03.627 に答える
14

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

詳細については、プルのドキュメントを参照してください。

ideidを使用してエンティティからすべてのフィールドを取得するには、次のようにします。

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

プルはクエリでも使用できます。

(datomic.api/q '[:find (pull ?e [*])
                 :where
                 [?e :myapp/name]
               (db conn))
于 2015-09-03T14:07:29.463 に答える
10

datomic.api/touch関数

エンティティのすべての属性を 「タッチ」するための特定のdatomic.api/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 "gretchen@user.com", :user/password "xxxxxx", :db/id 17592186046433}
于 2014-12-29T10:56:39.450 に答える
7

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

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

于 2013-01-07T04:35:51.690 に答える
0

私はそれをテストしていませんが、私が正しく覚えていれば、属性名として変数を置くことができます

(datomic.api/q '[:find ?key ?value
             :where
             [?e ?key ?value]]
           (db conn))
于 2013-01-07T18:48:29.413 に答える