26. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
27. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
28. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
29. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
30. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
31. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
32. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
// Traverse the node space and print out the result
33. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
// Traverse the node space and print out the result
System.out.println( "Mr Anderson's friends:" );
34. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
// Traverse the node space and print out the result
System.out.println( "Mr Anderson's friends:" );
for ( Node friend : friendsTraverser )
35. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
// Traverse the node space and print out the result
System.out.println( "Mr Anderson's friends:" );
for ( Node friend : friendsTraverser )
{
36. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
// Traverse the node space and print out the result
System.out.println( "Mr Anderson's friends:" );
for ( Node friend : friendsTraverser )
{
System.out.printf( "At depth %d => %s%n",
37. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
// Traverse the node space and print out the result
System.out.println( "Mr Anderson's friends:" );
for ( Node friend : friendsTraverser )
{
System.out.printf( "At depth %d => %s%n",
friendsTraverser.currentPosition().getDepth(),
38. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
// Traverse the node space and print out the result
System.out.println( "Mr Anderson's friends:" );
for ( Node friend : friendsTraverser )
{
System.out.printf( "At depth %d => %s%n",
friendsTraverser.currentPosition().getDepth(),
friend.getProperty( "name" ) );
39. // Instantiate a traverser that returns Mr Anderson's friends
Traverser friendsTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
RelTypes.KNOWS,
Direction.OUTGOING );
// Traverse the node space and print out the result
System.out.println( "Mr Anderson's friends:" );
for ( Node friend : friendsTraverser )
{
System.out.printf( "At depth %d => %s%n",
friendsTraverser.currentPosition().getDepth(),
friend.getProperty( "name" ) );
}
46. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
47. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
48. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
has_n :friends
49. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
has_n :friends
end
50. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
has_n :friends
end
Neo4j::Transactoin.run do
51. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
has_n :friends
end
Neo4j::Transactoin.run do
neo = Person.new :name=>'Neo', :age=>29
52. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
has_n :friends
end
Neo4j::Transactoin.run do
neo = Person.new :name=>'Neo', :age=>29
morpheus = Person.new :name=>'Morpheus', :occupation=>'badass'
53. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
has_n :friends
end
Neo4j::Transactoin.run do
neo = Person.new :name=>'Neo', :age=>29
morpheus = Person.new :name=>'Morpheus', :occupation=>'badass'
neo.friends << morpheus
54. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
has_n :friends
end
Neo4j::Transactoin.run do
neo = Person.new :name=>'Neo', :age=>29
morpheus = Person.new :name=>'Morpheus', :occupation=>'badass'
neo.friends << morpheus
end
55. gem install neo4j
require ”rubygems”
require 'neo4j'
class Person
include Neo4j::NodeMixin
property :name, :age, :occupation
index :name
has_n :friends
end
Neo4j::Transactoin.run do
neo = Person.new :name=>'Neo', :age=>29
morpheus = Person.new :name=>'Morpheus', :occupation=>'badass'
neo.friends << morpheus
end
neo.friends.each {|p|...}
58. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
59. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
60. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
61. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
62. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
63. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
64. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
65. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
match (a)-[:KNOWS]->(b)-[:KNOWS]->(c), (a)-[:BLOCKS]-(d)-
[:KNOWS]-(c)
66. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
match (a)-[:KNOWS]->(b)-[:KNOWS]->(c), (a)-[:BLOCKS]-(d)-
[:KNOWS]-(c)
return a,b,c,d
67. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
match (a)-[:KNOWS]->(b)-[:KNOWS]->(c), (a)-[:BLOCKS]-(d)-
[:KNOWS]-(c)
return a,b,c,d
//Where RegExp
68. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
match (a)-[:KNOWS]->(b)-[:KNOWS]->(c), (a)-[:BLOCKS]-(d)-
[:KNOWS]-(c)
return a,b,c,d
//Where RegExp
start n=(2, 1) where n.name =~ /Tob.*/ return n
69. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
match (a)-[:KNOWS]->(b)-[:KNOWS]->(c), (a)-[:BLOCKS]-(d)-
[:KNOWS]-(c)
return a,b,c,d
//Where RegExp
start n=(2, 1) where n.name =~ /Tob.*/ return n
//FOAF
70. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
match (a)-[:KNOWS]->(b)-[:KNOWS]->(c), (a)-[:BLOCKS]-(d)-
[:KNOWS]-(c)
return a,b,c,d
//Where RegExp
start n=(2, 1) where n.name =~ /Tob.*/ return n
//FOAF
start user = (people-index,name,”John”)
71. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
match (a)-[:KNOWS]->(b)-[:KNOWS]->(c), (a)-[:BLOCKS]-(d)-
[:KNOWS]-(c)
return a,b,c,d
//Where RegExp
start n=(2, 1) where n.name =~ /Tob.*/ return n
//FOAF
start user = (people-index,name,”John”)
match (user)-[:friend]->()-[:friend]->(foaf)
72. Cypher - Pattern Matcing für alle
//All nodes related to n
start n=(3) match (n)--(x) return x
//All nodes that are BLOCKed by A
start n=(3) match (n)-[:BLOCKS]->(x) return x
//All BLOCKS relationships outgoing from n
start n=(3) match (n)-[r, :BLOCKS]->() return r
//Diamond shape pattern
start a=(3)
match (a)-[:KNOWS]->(b)-[:KNOWS]->(c), (a)-[:BLOCKS]-(d)-
[:KNOWS]-(c)
return a,b,c,d
//Where RegExp
start n=(2, 1) where n.name =~ /Tob.*/ return n
//FOAF
start user = (people-index,name,”John”)
match (user)-[:friend]->()-[:friend]->(foaf)
return user, foaf
75. g = new Neo4jGraph('/tmp/neo4j')
// calculate basic collaborative filtering for vertex
1
76. g = new Neo4jGraph('/tmp/neo4j')
// calculate basic collaborative filtering for vertex
1
m = [:]
77. g = new Neo4jGraph('/tmp/neo4j')
// calculate basic collaborative filtering for vertex
1
m = [:]
g.v(1).out('likes').in('likes').out('likes').groupCou
nt(m)
78. g = new Neo4jGraph('/tmp/neo4j')
// calculate basic collaborative filtering for vertex
1
m = [:]
g.v(1).out('likes').in('likes').out('likes').groupCou
nt(m)
m.sort{a,b -> a.value <=> b.value}
80. Financial data – fraud detection
name = ...
name = “The Tavern”
lat = 1295238237
name = “Mr Godfather”
long = 234823492
W
42
karma = veeeery-low
D RA
cash = more-than-you amount = $1000 H
IT
W
OWNS TRANSFER WIT
1 7 3 HDR
AW
13
FER
DE name = “Emil”
PO cash = always-too-li'l
TRANS
SI
T
title = “ATM @ Wall St”
id = 230918484233
amount = $1000 cash_left = 384204
2
name = ...
We have key-value stores, typically very highly available and scalable for simple key-value data\n
Column stores naturally-indexed value stores\n\nContrary to common belief &#x2013; Google&#x2019;s big table isn&#x2019;t the world&#x2019;s most famous column store\n\nBritish museum London is: it&#x2019;s got columns and it&#x2019;s where we stored all the stuff we nicked from the British Empire!\n
Document DB&#x2019;s support for large-scale document storage, indexing documents, and processing them with batch-oriented frameworks.\n
We have graph databases that are well suited to complex, interconnected data\n\nSide note: Graph DB&#x2019;s are unique in the NOSQL world, that they&#x2019;re the only class of store that has a more expressive data model than RDBMS &#x2013; all the others have gone for simpler data models to achieve scale/availability/throughput\n
Each database pulls various levers to achieve its aims:\n\nDurable -> ordered writes -> take your chances\nSharded -> replicated -> take your chances\nConsistent -> eventually consistent -> take your chances\n\nNeo4j takes the ACID always approach\n
We should be in data-Nirvana\n\nWe have a range of data models to choose from\nWe have a range of products to select that support those models\nWe have a range of tuning that we can apply to those products \n\nWe should be able to craft exactly the right platform for our data needs\n
And then we fall back on old habits: trying to find the one true Database to rule them all. \n*sigh*\n\nKV stores pushing up against Document stores\nColumn stores pushing up against KV stores\nDocument stores wading into graphs\n\nAnd all the time all four NOSQL models are being poorly grafted onto our deal old RDMBS&#x2019;es!\n
Let&#x2019;s take a closer look at the damage we&#x2019;re doing\n
We can encode shallow graph-like data in document stores if we like (or even RDBMS like twitter)\n\nIt starts off looking nice and easy!\n
At runtime the application code sucks in the data and reifies a graph.\n\nOK, so that&#x2019;s code you have to test and write, but the datamodel is just documents, so that&#x2019;s OK right?\n
Compared to a graph database, it&#x2019;s actually hard work\n\nA graph DB stores data naturally in graphs so you don&#x2019;t have to deal with that concern in your code &#x2013; you deal with true application concerns \n\n-> index free traversal of big data FAST\n
I&#x2019;ve got a bad feeling about this&#x2026;\n
Imagine we want to sell things to our little social network\n\nIn a graph it&#x2019;s easy to record purchase history as relationships between buyers and products (and it doesn&#x2019;t slow down as buyers and products grow in number unlike joins in a relational DB)\n\nIn a document DB, the structure is implicit, and it&#x2019;s up to our application code to make sense of it.\nWhat do we do here? Put buyers in the product documents? Products in the people documents? Create purchase documents that join the two?\n\nWhat about a product recall, or social selling (example later on)?\nIn a graph DB it&#x2019;s O(1) search operation to find out who bought a product.\nIn a document DB it&#x2019;s an O(N) compute job to figure this out\n
EE\n
EE\n
EE\n
Lightweight and embedded: single jar of ~500k [demo]\n
Fully transactional: ie complete ACID, supports JTA/JTS, 2PC, deadlock detection, transaction recovery and all the rest [demo]\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Graphs over 1M nodes\nNetwork Management\nMaster Data Management\nSocial\nFinance\nSpatial\nOther\nBioinformatics\nRDF\nRouting, Logistics\n\n
Storage:\nplugable &#x2013; dataset, layer, encoder\nSearch:\nIndexing is currently an R-Tree, but it is possible to plug in any custom mechanism conforming to the interface.\nMulti-dimensional index\nSpatial indices (quad-tree, R-tree, kn-tree, SFCs)\nComposite indices and dynamic indices\nLucene\n
EE\n
&#x2022; includes high performance graph algorithms\n&#x2022; routes with live changing data \n&#x2022; integrates easily with any domain graph\n
We have graph databases that are well suited to complex, interconnected data\n\nSide note: Graph DB&#x2019;s are unique in the NOSQL world, that they&#x2019;re the only class of store that has a more expressive data model than RDBMS &#x2013; all the others have gone for simpler data models to achieve scale/availability/throughput\n
&#x2022; traverses millions of friends per second\n&#x2022; maps directly to friend-of-a-friend\n&#x2022; quickly performs deep recommendations\n
&#x2022; can handle billions of ad-hoc relationships \n&#x2022; traverses millions of nodes per second\n&#x2022; maps directly to your MDM domain\n
&#x2022; can handle billions of ad-hoc relationships \n&#x2022; traverses millions of nodes per second\n&#x2022; maps directly to your MDM domain\n
&#x2022; can handle billions of ad-hoc relationships \n&#x2022; traverses millions of nodes per second\n&#x2022; maps directly to your MDM domain\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Storage:\nplugable &#x2013; dataset, layer, encoder\nSearch:\nIndexing is currently an R-Tree, but it is possible to plug in any custom mechanism conforming to the interface.\nMulti-dimensional index\nSpatial indices (quad-tree, R-tree, kn-tree, SFCs)\nComposite indices and dynamic indices\nLucene\n