Loading
XN Logic Corporation
This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.
Brought to you by
Mike buys a book online
Data Modeling is about going back and forth between the real-world (on the left) and the graph (on the right).
VS.
A fundamental building block of Pacer
Without extensions
def comments_to_posts_by(person)
person
.out_e(:POSTED)
.in_v(type: 'post')
.in_e(:IS_ABOUT)
.in_v(type: 'comment')
end
With extensions
def comments_to_posts_by(person)
person.posts.comments
end
What do they look like?
module Person
# ...
module Vertex
def posts
self.out_e(:POSTED).in_v(type: 'post')
end
end
# ...
end
$ cd pacer-northwind
$ irb
jruby-1.7.18 :001 > require 'pacer'
=> true
jruby-1.7.18 :002 > g = Pacer.tg
=> #<PacerGraph tinkergraph[vertices:0 edges:0]
jruby-1.7.18 :003 > Pacer::GraphML.import(g, 'northwind.graphml')
=> true
From the root folder of our repo
And then
# Find out the different types of vertices ...
jruby-1.7.18 :004 > g.v[:type].uniq
"Order" "Category" "Employee"
"Customer" "Product" "Supplier"
Total: 6
Let's explore the dataset ...
# Look at an outgoing edge from a Customer vertex ...
jruby-1.7.18 :005 > e = g.v(type: 'Customer').out_e.limit(1)
#<E[e3026]:n10-PURCHASED-n255>
Total: 1
# What is the type of the in-vertex of that edge?
jruby-1.7.18 :033 > e.in_v.first[:type]
=> "Order"
In a file called customer.rb
module NorthWind
module Customer
end
end
module NorthWind
module Customer
module Vertex
end
end
end
module NorthWind
module Customer
module Vertex
def orders
end
end
end
end
module NorthWind
module Customer
module Vertex
def orders
self.out_e(:PURCHASED).in_v(type: "Order")
end
end
end
end
Try it in the IRB ...
jruby-1.7.18 :100 > load 'customer.rb'
=> true
jruby-1.7.18 :101 > c = g.v(NorthWind::Customer,
type: 'Customer').first
=> #<V[n10]>
jruby-1.7.18 :102 > c.orders
#<V[n255]> #<V[n913]> #<V[n450]> #<V[n505]> #<V[n989]>
#<V[n504]> #<V[n909]> #<V[n437]> #<V[n544]> #<V[n565]>
Total: 10
g.v
The vertex responds to the vertex-extension method.
g.v(NorthWind::Customer, type: 'Customer').first
g.v(NorthWind::Customer, type: 'Customer')
g.v( type: 'Customer')
orders
Only vertices whose type is 'Customer' should be extended by the Customer extension.
module NorthWind
module Customer
module Vertex
def orders
self.out_e(:PURCHASED).in_v(type: "Order")
end
end
end
end
def self.route_conditions(graph)
{type: 'Customer'}
end
jruby-1.7.18 :103 > load 'customer.rb'
=> true
jruby-1.7.18 :104 > include NorthWind
=> Object
jruby-1.7.18 :105 > g.v(Customer).first.orders
#<V[n255]> #<V[n913]> #<V[n450]> #<V[n505]> #<V[n989]>
#<V[n504]> #<V[n909]> #<V[n437]> #<V[n544]> #<V[n565]>
Total: 10
Try to get the orders of multiple customers ...
jruby-1.7.18 :106 > g.v(Customer).orders
NoMethodError
...
Total: 91
undefined method `orders' for
#<GraphV -> V-Property(NorthWind::Customer)>
We want to be able to extend routes, not just vertices.
module NorthWind
module Customer
def self.route_conditions(graph)
{type: "Customer"}
end
module Vertex # Contains vertex extension methods
# ...
end
module Route # Contains route extension methods
def orders
self.out_e(:PURCHASED).in_v(type: "Order")
end
end
end
end
jruby-1.7.18 :107 > load 'customer.rb'
=> true
jruby-1.7.18 :108 > g.v(Customer).limit(3).orders
#<V[n255]> #<V[n913]> #<V[n450]> #<V[n505]> #<V[n989]>
#<V[n504]> #<V[n909]> #<V[n437]> #<V[n544]> #<V[n565]>
#<V[n225]> #<V[n487]> #<V[n903]> #<V[n1020]> #<V[n748]>
#<V[n847]> #<V[n785]>
Total: 17
=> #<GraphV -> V-Property(NorthWind::Customer) -> V-Range(-1...3)
-> outE(:PURCHASED) -> inV -> V-Property(type=="Order")>
Reload and try it in the IRB
jruby-1.7.18 :109 > g.v(Customer).first.orders
#<V[n255]> #<V[n913]> #<V[n450]> #<V[n505]> #<V[n989]>
#<V[n504]> #<V[n909]> #<V[n437]> #<V[n544]> #<V[n565]>
Total: 10
=> #<outE(:PURCHASED) -> inV -> V-Property(type=="Order")>
Route-extension methods can be called on a single element:
* Because an element can be converted to a route with one element.
Customers have a few properties.
jruby-1.7.18 :111 > g.v(Customer).first
=> #<V[n10]>
Yet, in the IRB, we only display their internal id.
jruby-1.7.18 :110 > g.v(Customer).first.properties
=> {"phone"=>"(171) 555-1212",
"companyName"=>"B's Beverages",
"customerID"=>"BSBEV",
"type"=>"Customer"}
Can we define some sort of a toString method?
Add the following vertex extension method:
def display_name
"#{self[:companyName]} (#{self[:customerID]})"
end
And ...
jruby-1.7.18 :112 > load 'customer.rb'
=> true
jruby-1.7.18 :113 > g.v(Customer).first
=> #<V[n10] B's Beverages (BSBEV)>
Add a display_name to every extension you created.
After doing so, you should be able to do the following:
# Get a customer
jruby-1.7.18 :114 > c = g.v(Customer).first
=> #<V[n10] B's Beverages (BSBEV)>
# Get their orders
jruby-1.7.18 :115 > c.orders
#<V[n255] Order 10289> #<V[n913] Order 10947> #<V[n450] Order 10484> ...
Total: 10
# Get the employees who sold something to this customer
jruby-1.7.18 :116 > c.orders.employees.uniq
#<V[n203] Robert King, Sales Representative> ...
Total: 7
# Which other customers did these employees serve?
jruby-1.7.18 :117 > c.orders
jruby-1.7.18 :118 > .employees.uniq
jruby-1.7.18 :119 > .orders.customers
jruby-1.7.18 :120 > .uniq.is_not(c)
#<V[n59] Princesa Isabel Vinhos (PRINI)> #<V[n75] Suprêmes délices (SUPRD)> ...
Total: 89
We have seen the basic concepts for Data Modeling using Pacer.
Next, we will go through