-
Notifications
You must be signed in to change notification settings - Fork 100
/
Copy pathpull_recursion.clj
62 lines (51 loc) · 2.13 KB
/
pull_recursion.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
; Copyright (c) Cognitect, Inc. All rights reserved.
; The use and distribution terms for this software are covered by the
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
; which can be found in the file epl-v10.html at the root of this distribution.
; By using this software in any fashion, you are agreeing to be bound by
; the terms of this license.
; You must not remove this notice, or any other, from this software.
(require '[datomic.api :as d]
'[datomic.samples.repl :as repl])
(def db-uri "datomic:mem://test")
(d/create-database db-uri)
(def conn (d/connect db-uri))
;; define a schema of person entities where each person has a name and friends.
;; -- note that the friends are intended to be person entities themselves.
(def schema-tx
[{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :person/friend
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}])
@(d/transact conn schema-tx)
;; transact some people who have some friends.
(def people-tx
[{:db/id "anne-id"
:person/name "anne"
:person/friend #{"bob-id" "james-id"}}
{:db/id "bob-id"
:person/name "bob"
:person/friend #{"anne-id" "lucille-id"}}
{:db/id "james-id"
:person/name "james"
:person/friend #{"anne-id" "lucille-id"}}
{:db/id "lucille-id"
:person/name "lucille"
:person/friend #{"bob-id"}}])
@(d/transact conn people-tx)
(def db (d/db conn))
;; get the entity id for anne
(def anne-id
(d/q '[:find ?e . :where [?e :person/name "anne"]] db))
;; use pull to traverse the graph from anne through recursion:
;; a depth of 1
(d/pull db '[[:person/name :as :name] {[:person/friend :as :pals] 1}] anne-id)
;; a depth of 2
(d/pull db '[[:person/name :as :name] {[:person/friend :as :pals] 2}] anne-id)
;; expand all nodes reachable from anne
(d/pull db '[:person/name {:person/friend ...}] anne-id)
;; we can also traverse the graph in reverse (reverse ref in pull pattern)
(d/pull db '[:person/name {[:person/_friend :as :pals] 1}] anne-id)
(d/pull db '[:person/name {[:person/_friend :as :pals] ...}] anne-id)