105
A free guided tour of (Reality)-[:IS_A]->(Graph)

DevFest Istanbul - a free guided tour of Neo4J

Embed Size (px)

DESCRIPTION

2013-11-02 : DevFest Türkiye, Istanbul. Slightly modified version of my previous Neo4J introduction talk about Neo4J in Soft-Shake Event, Geneva, Switzerland.

Citation preview

Page 1: DevFest Istanbul - a free guided tour of Neo4J

A free guided tour of

(Reality)-[:IS_A]->(Graph)

Page 2: DevFest Istanbul - a free guided tour of Neo4J

What we have always known

selection sort (O(n2))

Page 3: DevFest Istanbul - a free guided tour of Neo4J

What we have always known

selection sort (O(n2))

|

heap sort (O(n*log(n))

Page 4: DevFest Istanbul - a free guided tour of Neo4J

What we have always known

selection sort (O(n2))

|

heap sort (O(n*log(n))

same algorithm, different data structure, better execution time !

Page 5: DevFest Istanbul - a free guided tour of Neo4J

What we have always known

1 data structure

1 usage

Page 6: DevFest Istanbul - a free guided tour of Neo4J

One NOSQL lesson?

1 data STORE

1 usage

Page 7: DevFest Istanbul - a free guided tour of Neo4J

One NOSQL lesson?

polyglot persistence, anyone ?

Page 8: DevFest Istanbul - a free guided tour of Neo4J
Page 9: DevFest Istanbul - a free guided tour of Neo4J

ZOOM on Graph Databases

graph=

nodes/vertices+

edges/relationships/arcs

Page 10: DevFest Istanbul - a free guided tour of Neo4J

Graph DB : a common model

property graph=

nodes+

labeled relationships+

K/V pairs

Page 11: DevFest Istanbul - a free guided tour of Neo4J

Graph DB : a common model

property graph=

labeledneov2 nodes+

labeled relationships+

K/V pairs

Page 12: DevFest Istanbul - a free guided tour of Neo4J

Property Graph DBs

Flock DB

Page 13: DevFest Istanbul - a free guided tour of Neo4J

Property Graph DBs

WHY DO THEY

KICK ASS?

Page 14: DevFest Istanbul - a free guided tour of Neo4J

BECAUSE

Page 15: DevFest Istanbul - a free guided tour of Neo4J

Graph-based computing

Intuitive model

Expressive querying

Powerful analyses

Page 16: DevFest Istanbul - a free guided tour of Neo4J

Graph-based computing

Intuitive model

Expressive querying

Powerful analyses

Whiteboard-friendliness

Pregel (GOOG), TAO (FB)

Pattern matching, path

finding...

Page 17: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases: mantra

RELATIONSHIPS

ARE AS IMPORTANT AS E N T I T I E S

Page 18: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Recommendations

People I may know ex: people known by contacts I have worked with in the past

Page 19: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Recommendations

People I may know ex: people known by contacts I have worked with in the past

Products I should buy ex: people who bought “Twilight” and“Justin Bieber biography” like you also bought “The ultimate emo guide”

Page 20: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Recommendations

People I may know ex: people known by contacts I have worked with in the past

Products I should buy ex: people who bought “Twilight” and“Justin Bieber biography” like you also bought “The ultimate emo guide”

Movies I should watch with whom and where...

Page 21: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Pattern detection

Fraud ex: many IPs from Fraudistan havemade a purchase of game X in the last hour

Page 22: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Pattern detection

Fraud ex: many IPs from Fraudistan havemade a purchase of game X in the last hour

Disease detection ex: DNA sequencing

Page 23: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Pattern detection

Fraud ex: many IPs from Fraudistan havemade a purchase of game X in the last hour

Disease detection ex: DNA sequencing

Trend detection ex: the term Flu has been tweeted 789% times more in Guatemala areain the last 24 hours

Page 24: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Path finding

Genealogy ex: is François Mitterand related toElizabeth II ? (yes)

Page 25: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Path finding

Genealogy ex: is François Mitterand related toElizabeth II ? (yes)

Navigation ex: what is the cheapest way to go to a sushi place < 15€ for me (Placede Clichy) and my friend (Place d’Italie)?

Page 26: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

Path finding

Genealogy ex: is François Mitterand related toElizabeth II ? (yes)

Navigation ex: what is the cheapest way to go to a sushi place < 15€ for me (Place de Clichy) and my friend (Place d’Italie)?

Impact analysis ex: which customers are impacted ifnetwork switch XYZ fails?

Page 27: DevFest Istanbul - a free guided tour of Neo4J

A glimpse at usecases

and more...

Topological ordering ex: given a set of dependencies, in which order should I include them?

Community detection ex: tag clustering on annotated resources to detect groups of interest(targeted advertising)

and much more...

Page 29: DevFest Istanbul - a free guided tour of Neo4J

In short

GRAPHS ARE

EVERYWHERE!

Page 30: DevFest Istanbul - a free guided tour of Neo4J

THAT’S WHYYOU

SHOULD TRY

Page 31: DevFest Istanbul - a free guided tour of Neo4J

Neo4J - the origins

Circa 2000, somewhere in Sweden

2 swedish guys hacking in a garage

Page 32: DevFest Istanbul - a free guided tour of Neo4J

Neo4J - the origins

Dialogue

- Man, I cannot stand Informix anymore

- Right, we’ve pushed it to the limit

- All these documents, these workflows…- Right, it’s way too densely connected.

- Connected… connections? CONNECTIONS??

Page 33: DevFest Istanbul - a free guided tour of Neo4J
Page 34: DevFest Istanbul - a free guided tour of Neo4J

Flash-forward: Neo Technology!

1 company Neo Technology

1 main product Neo4J

~50 employees

All over the world Sweden, US, Germany,

France, Malaysia, NZ...

Page 35: DevFest Istanbul - a free guided tour of Neo4J

Neo4J - moaar facts & figures

Versions 2.0.0.M06 / 1.9.4

Licenses GPL, AGPL, OEM, Commercial

235 nodes 34_359_738_368

235 relationships

> 236 properties at most 238

… capacity can be tailored on demand

Page 36: DevFest Istanbul - a free guided tour of Neo4J

Neo4J anatomy

Page 37: DevFest Istanbul - a free guided tour of Neo4J

GRAPH ON DISK(roughly)

original presentation: http://www.ustream.tv/channel/neo4j

Page 38: DevFest Istanbul - a free guided tour of Neo4J
Page 39: DevFest Istanbul - a free guided tour of Neo4J
Page 40: DevFest Istanbul - a free guided tour of Neo4J
Page 41: DevFest Istanbul - a free guided tour of Neo4J
Page 42: DevFest Istanbul - a free guided tour of Neo4J

COREAPI

Page 43: DevFest Istanbul - a free guided tour of Neo4J

Neo4J anatomy

Page 44: DevFest Istanbul - a free guided tour of Neo4J

Node CRUD (JVM)

GraphDatabaseService graphDB = new TestGraphDatabaseFactory ()

.newImpermanentDatabase();

try (Transaction transaction = graphDB.beginTx()) {

Node character=graphDB.createNode(DynamicLabel.label("CHARACTER"));

character.setProperty("name", "Homer Simpson");

transaction.success();

}

Page 45: DevFest Istanbul - a free guided tour of Neo4J

Node CRUD (JVM)

GraphDatabaseService graphDB = new TestGraphDatabaseFactory()

.newImpermanentDatabase();

try (Transaction transaction = graphDB.beginTx()) {

Node character=graphDB.createNode(DynamicLabel.label("CHARACTER"));

character.setProperty("name", "Homer Simpson");

transaction.success();

}

officially distributed

test version!

Page 46: DevFest Istanbul - a free guided tour of Neo4J

Node CRUD (JVM)

GraphDatabaseService graphDB = new TestGraphDatabaseFactory ()

.newImpermanentDatabase();

try (Transaction transaction = graphDB.beginTx()) {

Node character=graphDB.createNode(DynamicLabel.label("CHARACTER"));

character.setProperty("name", "Homer Simpson");

transaction.success();

}

transaction is MANDATORY

Java 7 required since 2.0

Page 47: DevFest Istanbul - a free guided tour of Neo4J

Node CRUD (JVM)

GraphDatabaseService graphDB = new TestGraphDatabaseFactory ()

.newImpermanentDatabase();

try (Transaction transaction = graphDB.beginTx()) {

Node character=graphDB.createNode(DynamicLabel.label("CHARACTER"));

character.setProperty("name", "Homer Simpson");

transaction.success();

}

labels are a way

to semi-structure your nodes

(since 2.0)

Page 48: DevFest Istanbul - a free guided tour of Neo4J

Node CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

for (Node node: graphDB.findNodesByLabelAndProperty(

DynamicLabel.label("CHARACTER"),

"name",

"Homer Simpson")) {

/* do something very useful */

}

transaction.success();

}

Page 49: DevFest Istanbul - a free guided tour of Neo4J

Node CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

for (Node node: graphDB.findNodesByLabelAndProperty(

DynamicLabel.label("CHARACTER"),

"name",

"Homer Simpson")) {

/* do something very useful */

}

transaction.success();

}

Gotchas

● avoid graphDB.findById !!!

● transaction is MANDATORY for reads as well (new in 2.0)

Page 50: DevFest Istanbul - a free guided tour of Neo4J

Node CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

Node character = /*lookup*/;

character.delete();

transaction.success();

}

Page 51: DevFest Istanbul - a free guided tour of Neo4J

Node CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

Node character = /*lookup*/;

character.delete();

transaction.success();

}

Gotchas

● no relationships must be attached when transaction commits

● all properties will be automatically removed

Page 52: DevFest Istanbul - a free guided tour of Neo4J

Relationship CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

Node homer = /*lookup*/;

Node doughnut = /*lookup*/;

Relationship eating = homer.createRelationshipTo(

doughnut,

DynamicRelationshipType .withName("LOVES_EATING")

);

eating.setProperty("quantity", Long.MAX_VALUE);

transaction.success();

}

Page 53: DevFest Istanbul - a free guided tour of Neo4J

Relationship CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

Node homer = /*lookup*/;

Node doughnut = /*lookup*/;

Relationship eating = homer.createRelationshipTo(

doughnut,

DynamicRelationshipType.withName("LOVES_EATING")

);

eating.setProperty("quantity", Long.MAX_VALUE);

transaction.success();

}

unrelated to

Node labels

Page 54: DevFest Istanbul - a free guided tour of Neo4J

Relationship CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

Node homer = /*lookup*/;

Node doughnut = /*lookup*/;

Relationship eating = homer.createRelationshipTo(

doughnut,

DynamicRelationshipType .withName("LOVES_EATING")

);

eating.setProperty("quantity", Long.MAX_VALUE);

transaction.success();

}Gotchas

● relationship direction matters at query time

● avoid human-eating doughnuts ;-)

Page 55: DevFest Istanbul - a free guided tour of Neo4J

Relationship CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

Relationship relationship = /*lookup*/;

relationship.delete();

transaction.success();

}

Page 56: DevFest Istanbul - a free guided tour of Neo4J

Relationship CRUD (JVM)

try (Transaction transaction = graphDB.beginTx()) {

Relationship relationship = /*lookup*/;

relationship.delete();

transaction.success();

}

Gotcha

● a write lock is set on the relationship, as well as both start AND end

nodes of the relationship

Page 57: DevFest Istanbul - a free guided tour of Neo4J

Core API

Low Level

Transactions are ALWAYS required (v2.0)

Technical IDs are dangerous (findById)

have a look at github.com/sarmbruster/neo4j-uuid

SAME capabilities with REST API

Page 58: DevFest Istanbul - a free guided tour of Neo4J

QUERYING

DATA

Page 59: DevFest Istanbul - a free guided tour of Neo4J

Neo4J anatomy

Page 60: DevFest Istanbul - a free guided tour of Neo4J

Two strategies

IMPERATIVE

VERY extensive

Totally customizable

100% under your

responsability

DECLARATIVE

VERY intuitive

90% of your needs

No free lunch (yet)!

Cypher PROFILE on its way

Page 61: DevFest Istanbul - a free guided tour of Neo4J

Two strategies

TRAVERSALS CYPHER QL

(/GREMLIN)

Page 62: DevFest Istanbul - a free guided tour of Neo4J

Traversals

DEPTH FIRST BREADTH FIRST

Page 63: DevFest Istanbul - a free guided tour of Neo4J

Traversals

Page 64: DevFest Istanbul - a free guided tour of Neo4J

Traversal - basic git log

try (Transaction transaction = graphDB.beginTx()) {

for (Path position : Traversal.description()

.depthFirst()

.evaluator(toDepth(LOG_DEFAULT_SIZE))

.relationships(

DynRelType.withName("PARENT_COMMIT"),

INCOMING

).traverse(headCommit)) {

Node currentNode = position.endNode;

logs.add(currentNode);

}

transaction.success();

}

Page 65: DevFest Istanbul - a free guided tour of Neo4J

Traversal - basic git log

try (Transaction transaction = graphDB.beginTx()) {

for (Path position : Traversal.description()

.depthFirst()

.evaluator(toDepth(LOG_DEFAULT_SIZE))

.relationships(

DynRelType.withName("PARENT_COMMIT"),

Direction.INCOMING

).traverse(headCommit)) {

Node currentNode = position.endNode;

logs.add(currentNode);

}

transaction.success();

}

lazy traversal

definition

Page 66: DevFest Istanbul - a free guided tour of Neo4J

Traversal - basic git log

try (Transaction transaction = graphDB.beginTx()) {

for (Path position : Traversal.description()

.depthFirst()

.evaluator(toDepth(LOG_DEFAULT_SIZE))

.relationships(

DynRelType.withName("PARENT_COMMIT"),

INCOMING

).traverse(headCommit)) {

Node currentNode = position.endNode;

logs.add(currentNode);

}

transaction.success();

}

start traversal

with node

Page 67: DevFest Istanbul - a free guided tour of Neo4J

Traversal - basic git log

try (Transaction transaction = graphDB.beginTx()) {

for (Path position : Traversal.description()

.depthFirst()

.evaluator(toDepth(LOG_DEFAULT_SIZE))

.relationships(

DynRelType.withName("PARENT_COMMIT"),

INCOMING

).traverse(headCommit)) {

Node currentNode = position.endNode;

logs.add(currentNode);

}

transaction.success();

}

keeps track of

current position

& visited nodes/rels

Page 68: DevFest Istanbul - a free guided tour of Neo4J

Traversals

Extensive

but verbose

and error-prone

WE <3 ASCII ART!

Page 69: DevFest Istanbul - a free guided tour of Neo4J

Pattern matching and ASCII art

WE <3

CYPHER

Page 70: DevFest Istanbul - a free guided tour of Neo4J

Pattern matching and ASCII art

Page 71: DevFest Istanbul - a free guided tour of Neo4J

Pattern matching and ASCII art

Page 72: DevFest Istanbul - a free guided tour of Neo4J

Pattern matching and ASCII art

Page 73: DevFest Istanbul - a free guided tour of Neo4J

Pattern matching and ASCII art

Page 74: DevFest Istanbul - a free guided tour of Neo4J

Pattern matching and ASCII art

Page 75: DevFest Istanbul - a free guided tour of Neo4J

Pattern matching and ASCII art

Page 76: DevFest Istanbul - a free guided tour of Neo4J

Cypher syntax with <3

Cypher

()-->()

Page 77: DevFest Istanbul - a free guided tour of Neo4J

Cypher

(A)-->(B)

Cypher syntax with <3

Page 78: DevFest Istanbul - a free guided tour of Neo4J

Cypher

(A)-[:LOVES]->(B)LOVES

Cypher syntax with <3

Page 79: DevFest Istanbul - a free guided tour of Neo4J

Cypher

(C)<--(A)-->(B)-->(C)

A-->B-->C,A-->C

Cypher syntax with <3

Page 80: DevFest Istanbul - a free guided tour of Neo4J

Cypher reads

START <lookup> (optional)

MATCH <pattern>

WHERE <filtering>

RETURN <expression>

Page 81: DevFest Istanbul - a free guided tour of Neo4J

Cypher reads

MATCH (homer:HUMAN)-[:LOVES_EATING]->(doughnut:FOOD)

WHERE homer.name = "Homer Simpson"

AND doughnut.brand = "Fattylicious!"

RETURN homer

Page 82: DevFest Istanbul - a free guided tour of Neo4J

Cypher reads

MATCH (sugg:CONTACT)-[:IN_CONTACT*2..10]-(me:CONTACT)

WHERE me.name = "Florent Biville"

AND me <> sugg

RETURN me, sugg

Page 83: DevFest Istanbul - a free guided tour of Neo4J

Cypher reads

RULES OF THUMB

● MATCH for results

● use WHERE to filter (WHERE a-[:F]->b or NOT(a-[:F]->b))

● favour parameters over literals (exec. plan reuse)

● javacodegeeks.com: “optimizing Neo4j Cypher Queries”

Page 84: DevFest Istanbul - a free guided tour of Neo4J

Cypher writes

CREATE (UNIQUE) <expression>

MERGE <expression>

Page 85: DevFest Istanbul - a free guided tour of Neo4J

Cypher writes

CREATE (homer:HUMAN:DAD {name: "Homer Simpson"})

RETURN homer

Page 86: DevFest Istanbul - a free guided tour of Neo4J

Cypher writes

START homer = node:characters("name:Hom*")

MATCH (d:JUNK:FOOD)

WHERE d.brand = "Fattylicious!"

CREATE (homer)-[luv:LOVES_EATING {quantity:∞}]->(d)

RETURN luv

Page 87: DevFest Istanbul - a free guided tour of Neo4J

Cypher writes

MERGE (keanu:ACTOR {name:'Keanu Reeves'})

ON CREATE keanu

SET keanu.created = timestamp()

ON MATCH keanu

SET keanu.lastSeen = timestamp()

RETURN keanu

Page 88: DevFest Istanbul - a free guided tour of Neo4J

Cypher - I want moaaar

Declarative power

Super nice syntax

Evolutionary design with MERGE!

http://console.neo4j.org to try it out!

Cypher will the #1 way to query data!

Page 89: DevFest Istanbul - a free guided tour of Neo4J

OBJECT-GRAPH

MAPPING

Page 90: DevFest Istanbul - a free guided tour of Neo4J

With...

Page 91: DevFest Istanbul - a free guided tour of Neo4J

Spring Data

History ~2010

Rod Johnson, Scala last poet

Emil Eifrem, Neo Tech. founder & CEO

Page 92: DevFest Istanbul - a free guided tour of Neo4J

Spring Data

Familiar model for Spring apps

THIN common layer

Embraces diversity MongoDB

Redis

Neo4J

ElasticSearch…

Current version 2.3.1.RELEASE

Page 93: DevFest Istanbul - a free guided tour of Neo4J

Vanilla Neo4J repositories with Spring

@Repository

public class BranchRepository {

public Relationship createBranch(Node p, Node c, Map<String,?> props) {

try (Transaction transaction = graphDB.beginTx()) {

Relationship relationship = p.createRelationshipTo(

c,

DynamicRelationshipType .name("HAS_BRANCH")

);

for (Entry<String,?> entry:props.entrySet()) {

relationship.setProperty(entry .getKey(), entry.getValue());

}

transaction.success();

return relationship;

}}}

Page 94: DevFest Istanbul - a free guided tour of Neo4J

Vanilla Neo4J repositories with Spring

@Repository

public class BranchRepository {

public Relationship createBranch(Node p, Node c, Map<String,?> props) {

try (Transaction transaction = graphDB.beginTx()) {

Relationship relationship = p.createRelationshipTo(

commit,

DynamicRelationshipType .name("HAS_BRANCH")

);

for (Entry<String,?> entry:props.entrySet()) {

relationship.setProperty(entry .getKey(), entry.getValue());

}

transaction.success();

return relationship;

}}}

Page 95: DevFest Istanbul - a free guided tour of Neo4J

Spring Data Neo4J repositories

public interface BranchRepository extends GraphRepository< Branch> {

// look ma! no code!

}

Page 96: DevFest Istanbul - a free guided tour of Neo4J

Moaaar Spring Data Neo4J repositories

public interface BranchRepository extends GraphRepository< Branch> {

Iterable<Branch> findByNameLike(String name);

@Query("MATCH (p:PROJECT)-[b:HAS_BRANCH]->(c:COMMIT) RETURN b" )

Page<Branch> lookMaIveGotPages ();

Branch findByNameAndCommitIdentifierLike (String name, String commit);

}

Page 97: DevFest Istanbul - a free guided tour of Neo4J

Moaaar Spring Data Neo4J repositories

public interface BranchRepository extends GraphRepository< Branch> {

Iterable<Branch> findByNameLike(String name);

@Query("MATCH (p:PROJECT)-[b:HAS_BRANCH]->(c:COMMIT) RETURN b" )

Page<Branch> lookMaIveGotPages ();

Branch findByNameAndCommitIdentifierLike (String name, String commit);

}

Cool things

● boilerplate methods already provided

● you declare methods following a naming convention, Spring Data Neo4J

generates the right implementation for ya!

● YOU EXPOSE YOUR DOMAIN, no Nodes, no Relationships!

Page 98: DevFest Istanbul - a free guided tour of Neo4J

Spring Data Neo4J node entities

@NodeEntity

public class Person {

@GraphId

private Long id;

@Indexed(indexName = "people", type=FULLTEXT)

private String name;

@RelatedTo(type="OWNS", enforceTargetType = true)

private Car car;

@RelatedToVia(type="FRIEND_OF", direction = Direction.INCOMING)

private Iterable<Friendship> friendships;

@GraphTraversal(traversal = PeopleTraversalBuilder .class,

elementClass = Person.class, params = "persons")

private Iterable<Person> people;

}

Page 99: DevFest Istanbul - a free guided tour of Neo4J

Spring Data Neo4J relationship entities

@RelationshipEntity(type ="FRIEND_OF")

public class Friendship {

@StartNode

private Person person;

@EndNode

private Dog humansBestFriend;

@GraphProperty /* optional here ;-) */

private Date since;

/**

* moaaaaar properties

*/

}

Page 100: DevFest Istanbul - a free guided tour of Neo4J

Neo4jTemplate

Geospatial queries

Cross-store support

Dynamic relationships

“Advanced” mapping

And much more

Page 101: DevFest Istanbul - a free guided tour of Neo4J

Conclusion

Page 102: DevFest Istanbul - a free guided tour of Neo4J

So much to talk about, so little time

● moaaar Cypher

● REST

○ standard API

○ unmanaged extensions

○ streaming

● Tinkerpop abstractions, http://www.tinkerpop.com/

● dataviz

○ auto : http://linkurio.us/, Neoclipse, Gephi

○ custom : d3.js, sigma.js…● NeoAAS : http://www.graphenedb.com/, Heroku

● misc. : backup, batch-import, JDBC drivers

Page 103: DevFest Istanbul - a free guided tour of Neo4J

And one more thing

AssertJ-Neo4J 1.0 is coming soon!

Fluent test assertions for Neo4J

https://github.com/joel-costigliola/assertj-neo4j

Page 104: DevFest Istanbul - a free guided tour of Neo4J

SORUSU

OLAN?

Page 105: DevFest Istanbul - a free guided tour of Neo4J

@[email protected]

www.lateral-thoughts.com

Bana ulaşın