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
def orders
self.out_e(:PURCHASED).in_v(type: "Order")
end
Consider our Customer extension.
Instead of the following route extension method
def orders
self.out_e(:PURCHASED).in_v(NorthWind::Order)
end
We can define
* Assuming we have created a NorthWind::Order extension.
Now, we can traverse the graph by chaining extension methods:
# Get a customer from the graph
c = g.v(NorthWind::Customer).first
# Get their orders
c.orders
# Chain the result (the `Order` extension has a
# `products` route extension method).
c.orders.products
# If all of our extensions are returning extended routes,
# our traversals start looking like this:
c.orders.products.categories.uniq
Go over all the extensions you've created, and make sure that extension methods return extended routes.
category = g.v(NorthWind::Category).first
category.products
category.products.orders.customers
# And even a slightly more complex traversal ...
g.v(NorthWind::Customer)
.lookahead(max: 1) do |c|
c.orders.employees.uniq
end
.uniq
When you're done, try to run some traversals in the IRB.
For example:
Instead of getting/setting properties as follows:
jruby-1.7.18 :018 > e = g.v(Employee).first
=> #<V[n202] Michael Suyama, Sales Representative>
jruby-1.7.18 :019 > e[:title] = "Senior Sales Representative"
=> "Senior Sales Representative"
jruby-1.7.18 :020 > e[:title]
=> "Senior Sales Representative"
We can define properties as vertex extensions
def title
self[:title]
end
def title=(new_title)
self[:title] = new_title
end
And use them
jruby-1.7.18 :021 > e = g.v(Employee).first
=> #<V[n202] Michael Suyama, Senior Sales Representative>
jruby-1.7.18 :022 > e.title = "Sales Representative"
=> "Sales Representative"
jruby-1.7.18 :023 > e.title
=> "Sales Representative"
# We don't actually store a `name` property.
# Instead, we compute it on demand.
def name
"#{self[:firstName]} #{self[:lastName]}"
end
Simple technique that leads to slightly cleaner code:
e[:title]
e[:title] = 'Boss'
e.title
e.title = 'Boss'
VS.
Properties that are computed on-demand
After reloading the code, you should be able to do
product = g.v(Product).first
# Test the getter
name = product.name
# Test the setter
product.name = 'foo'
Let's look at how orders are stored:
jruby-1.7.18 :205 > o = g.v(Order).first
=> #<V[n819] Order 10853>
jruby-1.7.18 :206 > o.out_e
#<E[e1589]:n819-PRODUCT-n108>
jruby-1.7.18 :207 > o.out_e(:PRODUCT).properties
{"unitPrice"=>62.5, "quantity"=>10.0}
Essentially, the edge from an Order to a Product serves as an order item:
Create an edge extension, in a file called order_item.rb
module NorthWind
module OrderItem
module Edge # Containing Edge extension methods
def order
self.out_vertex(NorthWind::Order)
end
def product
self.in_vertex(NorthWind::Product)
end
# ...
end
end
end
Use the extension
jruby-1.7.18 :207 > load 'order_item.rb'
=> true
jruby-1.7.18 :208 > o = g.v(Order).first
=> #<V[n819] Order 10853>
jruby-1.7.18 :209 > o.out_e(OrderItem)
#<E[e1589]:10.0 units of Carnarvon Tigers at 62.5$/unit>
Total: 1
=> #<outE -> E>
jruby-1.7.18 :210 > o.out_e(OrderItem).first.order
=> #<V[n819] Order 10853>
jruby-1.7.18 :211 > o.out_e(OrderItem).first.product
=> #<V[n108] Carnarvon Tigers, 62.5$>
Add the following edge extension methods to OrderItem:
As you might expect, we can define which edges can be extended by OrderItem
module NorthWind
module OrderItem
# Extend only edges whose label is PRODUCT
def self.route_conditions(graph)
:PRODUCT
end
# ...
We can also create route extension methods.
module NorthWind
module OrderItem
# ...
module Route
def products
self.in_v(NorthWind::Product)
end
# ...
end
# ...
Use the products extensions method on a route of order items:
# Get (a route containing) a few order items
items = g.e(NorthWind::OrderItem).limit(3)
# And their products
items.products
Add the orders route extensions method to OrderItem.
NOTE: Although Pacer supports edge extensions, we recommend to keep your edges property-free, if possible.
We can turn
Into
Flexibility - We can have edges to/from the new vertex.
Index properties frequently used for searching.
jruby-1.7.18 :068 > g.v(type: 'foo')
Total: 0
=> #<GraphV -> V-Property(type=="foo")>
jruby-1.7.18 :069 > g.create_key_index :type
jruby-1.7.18 :070 > g.v(type: 'foo')
Total: 0
=> #<V-Index(type: "foo")>
Create an index on the type property:
We will see a demo of a full web application, backed by a graph database.