Loading

Graph Training 2

XN Logic Corporation

This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.

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

$ 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
Made with Slides.com