Graph Traversal Using Pacer

Brought to you by
In this section ...
- CRUD operations
- Basic traversals
- Composing basic traversals into complex ones
Hands-on introduction to graph databases
Setup Pacer
Step 1: Install dependencies
$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
$ \curl -sSL https://get.rvm.io | bash -s stable
$ rvm install jruby
$ gem install pacer
Step 2: Start the IRB and load Pacer
$ irb
jruby-1.7.18 :001 > require 'pacer'
=> true
Step 3: Create a Graph
jruby-1.7.18 :002 > g = Pacer.tg()
=> #<PacerGraph tinkergraph[vertices:0 edges:0]
Windows users may want to try
jirb_swing

Creating elements ...
jruby-1.7.19 :003 > v1 = g.create_vertex()
=> #<V[0]>
jruby-1.7.19 :004 > v2 = g.create_vertex()
=> #<V[1]>

graph.create_vertex

vertex.add_edges_to
jruby-1.7.19 :005 > v1.add_edges_to(:likes, v2)
#<E[2]:0-likes-1>
Total: 1
=> #<Obj 1 ids -> lookup -> is_not(nil)>
jruby-1.7.18 :006 > v2.add_edges_to(:dislikes, v1)
#<E[3]:1-dislikes-0>
Total: 1
=> #<Obj 1 ids -> lookup -> is_not(nil)>
In most cases, you probably want to create elements with properties ...
alice = g.create_vertex({type: 'person', name: 'Alice'})
bob = g.create_vertex({type: 'person', name: 'Bob'})
post = g.create_vertex({type: 'post',
text: 'Learning about Pacer ...'})
alice.add_edges_to( :follows, bob, {since: Time.now})
bob.add_edges_to( :posted, post, {timestamp: Time.now})
alice.add_edges_to( :likes, post, {timestamp: Time.now})
Getting elements ...
graph.v
Get all vertices in the graph
jruby-1.7.18 :007 > g.v
#<V[0]> #<V[1]> #<V[2]>
Total: 3
=> #<GraphV>
graph.vertex
Get a specific vertex by its id
jruby-1.7.18 :008 > g.vertex(1)
=> #<V[1]>
graph.e
Get all edges in the graph
jruby-1.7.18 :009 > g.e
#<E[3]:0-follows-1> #<E[4]:1-posted-2> #<E[5]:0-likes-2>
Total: 3
=> #<GraphE>
graph.edge
Get a specific edge by its id
jruby-1.7.18 :010 > g.edge(4)
=> #<E[4]:1-posted-2>
Routes are collections/streams of elements.
- Reusable
- Lazily loaded
- Composable
return a Route object.
If you are not familiar with some of the terminology, don't worry, we will go into more details later.
For now, just think of routes as plain old collections.
graph.v / graph.e
Routes
Useful Route Methods
g.v.first
Get the first element
Return value is a single element
g.e[2..4]
Get a range of elements
Return value is a collection/route of elements
g.v.each {|v| do_something_with(v)}
Go through the elements
By property value
jruby-1.7.18 :011 > g.v(type: 'person')
#<V[0]> #<V[1]>
Total: 2
=> #<GraphV -> V-Property(type=="person")>
jruby-1.7.18 :012 > g.e(:likes)
#<E[5]:0-likes-2>
Total: 1
=> #<GraphE -> E-Property(:likes)>
On, in the case of edges, by edge-label
Basic Filtering
Traversing The Graph ...
Basic Traversal
some_vertex.out_e.in_v
some_vertex
some_vertex.out_e
some_vertex.in_e.out_v
some_vertex
some_vertex.in_e
out_e, in_e, both_e
jruby-1.7.18 :013 > bob = g.v(name: 'Bob').first
=> #<V[1]>
jruby-1.7.18 :014 > bob.out_e
#<E[4]:1-posted-2>
Total: 1
=> #<outE>
jruby-1.7.18 :015 > bob.in_e
#<E[3]:0-follows-1>
Total: 1
=> #<inE>
jruby-1.7.18 :016 > bob.both_e
#<E[3]:0-follows-1> #<E[4]:1-posted-2>
Total: 2
=> #<bothE>
out_e, in_e, both_e
jruby-1.7.18 :017 > g.v.out_e
#<E[3]:0-follows-1> #<E[5]:0-likes-2> #<E[4]:1-posted-2>
Total: 3
=> #<GraphV -> outE>
Can be called on a single element as well as a route
out_v, in_v, both_v
jruby-1.7.18 :018 > e = g.e.first
=> #<E[3]:0-follows-1>
jruby-1.7.18 :019 > e.out_v
#<V[0]>
Total: 1
=> #<outV>
jruby-1.7.18 :020 > e.in_v
#<V[1]>
Total: 1
=> #<inV>
jruby-1.7.18 :021 > e.both_v
#<V[0]> #<V[1]>
Total: 2
=> #<bothV>
out_v, in_v, both_v
jruby-1.7.18 :022 > g.e.out_v
#<V[0]> #<V[1]> #<V[0]>
Total: 3
=> #<GraphE -> outV>
Can be called on a single element as well as a route
out_vertex, in_vertex
jruby-1.7.18 :023 > g.e.first.out_vertex
=> #<V[0]>
Get a single vertex (not a route) from an edge
Properties ...
Getting Properties
jruby-1.7.18 :024 > g.v(type: 'person').first.properties
=> {"name"=>"Alice", "type"=>"person"}
jruby-1.7.18 :025 > g.v(type: 'person').properties
{"name"=>"Alice", "type"=>"person"}
{"name"=>"Bob", "type"=>"person"}
Total: 2
=> #<GraphV -> V-Property(type=="person") -> Hash-Map>
All properties of an element
Return value is a hash
All properties of every element in a route
Return value is a route of hashes
Getting Properties
jruby-1.7.18 :026 > g.v(type: 'person').first[:name]
=> "Alice"
jruby-1.7.18 :027 > g.v(type: 'person')[:name]
"Alice" "Bob"
Total: 2
=> #<GraphV -> V-Property(type=="person") -> Obj(name) -> decode>
Specific property of an element
Specific property of every element in a route
Return value is a route
Setting Properties
jruby-1.7.18 :028 > alice = g.v(name: 'Alice').first
=> #<V[0]>
jruby-1.7.18 :029 > alice.properties
=> {"name"=>"Alice", "type"=>"person"}
jruby-1.7.18 :030 > alice[:age] = 32
=> 32
jruby-1.7.18 :031 > alice.properties
=> {"name"=>"Alice", "type"=>"person", "age"=>32}
Deleting Properties
jruby-1.7.18 :031 > alice.properties
=> {"name"=>"Alice", "type"=>"person", "age"=>32}
jruby-1.7.18 :032 > alice[:age] = nil
=> nil
jruby-1.7.18 :033 > alice.properties
=> {"name"=>"Alice", "type"=>"person"}
Note: You cannot set/delete property on a route!
g.v(name: 'Alice')[:name] = 'foo'
g.v(name: 'Alice').first[:name] = 'foo'


jruby-1.7.18 :034 > g.e
#<E[3]:0-follows-1> #<E[4]:1-posted-2> #<E[5]:0-likes-2>
Total: 3
=> #<GraphE>
jruby-1.7.18 :035 > g.e.first.delete!
=> nil
jruby-1.7.18 :036 > g.e
#<E[4]:1-posted-2> #<E[5]:0-likes-2>
Total: 2
=> #<GraphE>
A single element
delete!
Deleting Elements
jruby-1.7.18 :062 > g.v.delete!
Bulk job -> 0!
Bulk job -> 0!
=> 5
jruby-1.7.18 :063 > g.v
Total: 0
=> #<GraphV>
Every element in a route
delete!
Deleting Elements
Note: Deleting a vertex also deletes all of its edges.
Summary
- Creating graphs, vertices and edges
- Getting elements from a graph
- Single element vs. route
- Filter based on property value and/or edge label
- Basic traversal
-
vertex_or_route.out_e.in_v
-
vertex_or_route.in_e.out_v
-
- Getting/setting properties
- Deleting elements
People should be able to:
- Post posts
- Comment on posts
- Comment on comments
Exercise
person
-
type
-
name
Comment
-
type
-
text
-
timestamp
post
-
type
-
text
-
timestamp
Exercise
Get the code
git clone git@github.com:xnlogic/graph-training.git
cd graph-training/exercises
Install MiniTest
gem install minitest
Run the tests
ruby ex1-test.rb
Edit ex1.rb until you get to
28 runs, 46 assertions, 0 failures, 0 errors, 0 skips
You should expect to get
28 runs, 15 assertions, 15 failures, 13 errors, 0 skips
Graph Training 2
By XN Logic Corporation
Graph Training 2
Graph processing, using the Pacer library - CRUD operations, basic traversals, creating complex traversals by composing basic ones.
- 1,070