Graph Traversal Using Pacer

Brought to you by

Pacer Basics

$ 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 Data

Vertices

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

And edges

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)>

Creating Data

With some properties ...

jruby-1.7.18 :007 > alice = g.create_vertex({type: 'person', name: 'Alice'})
jruby-1.7.18 :008 > bob = g.create_vertex({type: 'person', name: 'Bob'})
jruby-1.7.18 :009 > alice.add_edges_to(:follows, bob, {since: Time.now})

Let's make our data set a bit more interesting ...

jruby-1.7.18 :010 > post = g.create_vertex({type: 'post', 
                                            text: 'Learning about Pacer ...'})
jruby-1.7.18 :011 > bob.add_edges_to(:posted, post, {timestamp: Time.now})
jruby-1.7.18 :012 > alice.add_edges_to(:likes, post, {timestamp: Time.now})

Reading Data

All vertices

jruby-1.7.18 :013 > g.v
#<V[0]> #<V[1]> #<V[4]> #<V[5]> #<V[7]>
Total: 5
 => #<GraphV>
  • In both cases, we get back a Route.
  • Routes are a fundamental concept in Pacer.
  • For now, think of a Route as a collection of elements.

All edges

jruby-1.7.18 :014 > g.e
#<E[11]:5-posted-7>  #<E[12]:4-likes-7>  #<E[2]:0-likes-1>  ...
Total: 8
 => #<GraphE>

Reading Data

Specific element, by id

jruby-1.7.18 :015 > g.vertex(5)
jruby-1.7.18 :016 > g.edge(5)

First element of a route

jruby-1.7.18 :017 > g.v.first

Range of elements from a route

jruby-1.7.18 :018 > g.v[2..4]
# The statement above is equivalent to
jruby-1.7.18 :019 > g.v.offset(2).limit(3)

Reading Data

Vertices with a given property value

jruby-1.7.18 :020 > g.v(type: 'person')
#<V[4]> #<V[5]>
Total: 2
 => #<GraphV -> V-Property(type=="person")>

Edges with a given label

jruby-1.7.18 :021 > g.e(:likes)
#<E[12]:4-likes-7> #<E[2]:0-likes-1>
Total: 2
 => #<GraphE -> E-Property(:likes)>

Traversing

Start from a vertex

jruby-1.7.18 :022 > bob = g.v(name: 'Bob').first
 => #<V[5]>
jruby-1.7.18 :023 > bob.out_e
#<E[11]:5-posted-7>
Total: 1
 => #<outE>
jruby-1.7.18 :024 > bob.in_e
#<E[6]:4-follows-5>
Total: 1
 => #<inE>
jruby-1.7.18 :025 > bob.both_e
#<E[6]:4-follows-5> #<E[11]:5-posted-7>
Total: 2
 => #<bothE>

And follow its edges:

Traversing

Start from an edge

jruby-1.7.18 :026 > e = g.e(:likes).first
 => #<E[12]:4-likes-7>
jruby-1.7.18 :027 > e.out_v
#<V[4]>
Total: 1
 => #<outV>
jruby-1.7.18 :028 > e.in_v
#<V[7]>
Total: 1
 => #<inV>
jruby-1.7.18 :029 > e.both_v
#<V[4]> #<V[7]>
Total: 2
 => #<bothV>

And get its vertices:

Traversing

out_v, in_v
out_vertex, in_vertex

Return a route

Return a vertex

jruby-1.7.18 :000 > edge.out_v
#<V[n89]>
Total: 1
 => #<outV>
jruby-1.7.18 :000 > edge.out_vertex
 => #<V[n89]>

vs.

Traversing

Same syntax for single item as for route:

jruby-1.7.18 :030 > alice = g.v(name: 'Alice').first
 => #<V[4]>
jruby-1.7.18 :031 > alice.out_e
#<E[6]:4-follows-5> #<E[12]:4-likes-7>
Total: 2
 => #<outE>
jruby-1.7.18 :032 > g.v(type: 'person').out_e
#<E[6]:4-follows-5> #<E[12]:4-likes-7>  #<E[11]:5-posted-7>
Total: 3
 => #<GraphV -> V-Property(type=="person") -> outE>

Common Patterns

 some_vertex.out_e.in_v
 some_vertex
 some_vertex.out_e
 some_vertex.in_e.out_v
 some_vertex
 some_vertex.in_e

Properties

All properties

jruby-1.7.18 :033 > g.v(type: 'person').first.properties
 => {"name"=>"Alice", "type"=>"person"}

jruby-1.7.18 :034 > g.v(type: 'person').properties
{"name"=>"Alice", "type"=>"person"}   {"name"=>"Bob", "type"=>"person"}
Total: 2
 => #<GraphV -> V-Property(type=="person") -> Hash-Map>

A specific property

jruby-1.7.18 :034 > g.v(type: 'person').first[:name]
 => "Alice"

jruby-1.7.18 :035 > g.v(type: 'person')[:name]
"Alice" "Bob"
Total: 2
 => #<GraphV -> V-Property(type=="person") -> Obj(name) -> decode>

Properties

Set the value of a property

jruby-1.7.18 :036 > alice = g.v(name: 'Alice').first
 => #<V[4]>
jruby-1.7.18 :037 > alice[:age] = 32
 => 32
jruby-1.7.18 :038 > alice.properties
 => {"name"=>"Alice", "type"=>"person", "age"=>32}

Delete property

jruby-1.7.18 :039 > alice[:age] = nil
 => nil
jruby-1.7.18 :040 > alice.properties
 => {"name"=>"Alice", "type"=>"person"}

Note: You can set/delete properties of a single item, not of a route.

Deleting Elements

Delete a single element

jruby-1.7.18 :041 > g.e.first.delete!
 => nil
jruby-1.7.18 :042 > g.v.first.delete!
 => nil

Delete all elements in a route

jruby-1.7.18 :043 > g.e.delete!
Bulk job -> 0!
 => 2

jruby-1.7.18 :044 > g.v.delete!
Bulk job ->!
Bulk job -> 0!
 => 4

jruby-1.7.18 :045 > g.v
Total: 0
 => #<GraphV>

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

Exercise

People should be able to:

  • Post posts
  • Follow other people
  • Comment on posts and other comments
  • Like posts and comments.

A simple social network

Exercise

Data model ...

  • Person
    • type
    • name
  • Post
    • type
    • text
    • timestamp
  • Comment
    • type
    • text
    • timestamp

Types correspond to values of the type property 

Instances of these objects correspond to vertices

GraphDB & Pacer 2

By Joey Freund

GraphDB & Pacer 2

Using Pacer to perform efficient graph processing on any Blueprint-enabled graph. In this section we will look at CRUD operations and basic graph traversals.

  • 577