SlideShare a Scribd company logo
1 of 48
Download to read offline
An	
  Introduc+on	
  to	
  Doctor	
  Who	
  
            (and	
  Neo4j)	
  
                   	
  
             @iansrobinson	
  
                #neo4j	
  
Neo4j	
  is	
  a	
  Graph	
  Database	
  




                                  #neo4j	
  
Property	
  Graph	
  




                        #neo4j	
  
Property	
  Graph	
  




                        #neo4j	
  
Neo4j	
  




            #neo4j	
  
#neo4j	
  
32	
  billion	
  nodes	
  
32	
  billion	
  rela+onships	
  
64	
  billion	
  proper+es	
  
#neo4j	
  
Community	
  


   Advanced	
  



      Enterprise	
  
stole	
        companion	
  
                                                from	
                                                         loves	
  
                                                                                              loves	
                                        appeared	
  	
  
                             enemy	
                                                                                                         in	
  
                                                                              companion	
  
                                                                                                                  appeared	
  	
  
                                                                                                                  in	
  

                                           appeared	
  	
  
                                           in	
                            enemy	
  

                                                               enemy	
  
appeared	
  	
                                                                                appeared	
  	
  
                                                                                                                           A	
  Good	
  Man	
  
       in	
                                                                                          in	
                  Goes	
  to	
  War	
  
                   Victory	
  of	
  	
  
                   the	
  Daleks	
  




                                                                                                          appeared	
  	
  
                                                                                                          in	
  
GraphDatabaseService db = new EmbeddedGraphDatabase("/data/drwho");
GraphDatabaseService db = new EmbeddedGraphDatabase("/data/drwho");




    Node theDoctor = db.createNode();
    theDoctor.setProperty("name", "The Doctor");

    Node daleks = db.createNode();
    daleks.setProperty("name", "Daleks");

    Node cybermen = db.createNode();
    cybermen.setProperty("name", "Cybermen");
GraphDatabaseService db = new EmbeddedGraphDatabase("/data/drwho");




    Node theDoctor = db.createNode();
                                                           enemy	
  
    theDoctor.setProperty("name", "The Doctor");

    Node daleks = db.createNode();
    daleks.setProperty("name", "Daleks");

    Node cybermen = db.createNode();
    cybermen.setProperty("name", "Cybermen");
                                                                       enemy	
  
    theDoctor.createRelationshipTo(daleks,
         DynamicRelationshipType.withName("enemy"));
    theDoctor.createRelationshipTo(cybermen,
         DynamicRelationshipType.withName("enemy"));
GraphDatabaseService db = new EmbeddedGraphDatabase("/data/drwho");

Transaction tx = db.beginTx();
try {
      Node theDoctor = db.createNode();
                                                           enemy	
  
      theDoctor.setProperty("name", "The Doctor");

     Node daleks = db.createNode();
     daleks.setProperty("name", "Daleks");

     Node cybermen = db.createNode();
     cybermen.setProperty("name", "Cybermen");
                                                                       enemy	
  
     theDoctor.createRelationshipTo(daleks,
          DynamicRelationshipType.withName("enemy"));
     theDoctor.createRelationshipTo(cybermen,
          DynamicRelationshipType.withName("enemy"));

      tx.success();
} finally {
      tx.finish();
}
How	
  do	
  I	
  query	
  the	
  data?	
  




hOp://opfm.jpl.nasa.gov/	
  




                                              hOp://news.xinhuanet.com	
  




                                                                             #neo4j	
  
Dalek	
  Props	
  
       hOp://www.dalek6388.co.uk/	
  




                         #neo4j	
  
species:Dalek	
  

                       APPEARED_IN	
  

                                                   !tle:Power	
  of	
  	
  
                                                    the	
  Daleks	
  

                            USED_IN	
  
                                                 props:Daleks	
  

MEMBER_OF	
                                                                   MEMBER_OF	
  
                                                                                       name:Dalek	
  Six-­‐5	
  

 name:Dalek	
  1	
                name:Dalek	
  2	
                  name:Dalek	
  7	
  




      type:shoulders	
         type:skirt	
  
name:Dalek	
  1	
     name:Dalek	
  2	
          name:Dalek	
  7	
     name:Dalek	
  Six-­‐5	
  
ORIGINAL_PROP	
        ORIGINAL_PROP	
  



                                                                        ORIGINAL_PROP	
  
                                             ORIGINAL_PROP	
  

                                                name:Dalek	
  6	
          name:Dalek	
  5	
  
!tle:The	
  
                                                                      !tle:Power	
  of	
  	
  
         !tle:The	
                       Dalek	
  
                                                                       the	
  Daleks	
  
          Daleks	
                     Invasion	
  of	
  
                                          Earth	
  




                                                                                                          name:	
  
                            name:Dalek	
  1	
          name:Dalek	
  2	
            name:Dalek	
  7	
     Dalek	
  Six-­‐5	
  




name:Dalek	
  Two-­‐1	
  
                            name:Dalek	
  One-­‐5	
          name:Dalek	
  Six-­‐7	
  
Supply	
  Chain	
  Traceability	
  




                              #neo4j	
  
Traversal	
  Framework	
  
•  Visits	
  (and	
  returns)	
  nodes	
  based	
  on	
  traversal	
  
   descrip+on	
  
•  Powerful;	
  can	
  customize:	
  
    –  Rela+onships	
  followed	
  
    –  Branch	
  selec+on	
  policy	
  
    –  Node/rela+onship	
  uniqueness	
  constraints	
  
    –  Path	
  evaluators	
  



                                                       #neo4j	
  
Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle();

Traverser traverser = Traversal.description()
  .depthFirst()
  .relationships(Rels.APPEARED_IN, Direction.OUTGOING)
  .relationships(Rels.USED_IN, Direction.INCOMING)
  .relationships(Rels.MEMBER_OF, Direction.INCOMING)
  .relationships(Rels.COMPOSED_OF, Direction.OUTGOING)
  .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING)
  .evaluator(new Evaluator() {
     @Override
     public Evaluation evaluate(Path path) {
       if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){
           return Evaluation.INCLUDE_AND_PRUNE;
       }
        return Evaluation.EXCLUDE_AND_CONTINUE;
    }
  })
  .uniqueness(Uniqueness.NONE)
  .traverse(theDaleks);                          Description
Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle();

Traverser traverser = Traversal.description()
  .depthFirst()
  .relationships(Rels.APPEARED_IN, Direction.OUTGOING)
  .relationships(Rels.USED_IN, Direction.INCOMING)
  .relationships(Rels.MEMBER_OF, Direction.INCOMING)
  .relationships(Rels.COMPOSED_OF, Direction.OUTGOING)
  .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING)
  .evaluator(new Evaluator() {
     @Override
     public Evaluation evaluate(Path path) {
       if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){
           return Evaluation.INCLUDE_AND_PRUNE;
       }
        return Evaluation.EXCLUDE_AND_CONTINUE;
    }
  })
  .uniqueness(Uniqueness.NONE)
  .traverse(theDaleks);                         Index Lookup
Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle();

Traverser traverser = Traversal.description()
  .depthFirst()
  .relationships(Rels.APPEARED_IN, Direction.OUTGOING)
  .relationships(Rels.USED_IN, Direction.INCOMING)
  .relationships(Rels.MEMBER_OF, Direction.INCOMING)
  .relationships(Rels.COMPOSED_OF, Direction.OUTGOING)
  .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING)
  .evaluator(new Evaluator() {
     @Override
     public Evaluation evaluate(Path path) {
       if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){
           return Evaluation.INCLUDE_AND_PRUNE;
       }
        return Evaluation.EXCLUDE_AND_CONTINUE;
    }
  })
  .uniqueness(Uniqueness.NONE)
  .traverse(theDaleks);                            Branching
Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle();

Traverser traverser = Traversal.description()
  .depthFirst()
  .relationships(Rels.APPEARED_IN, Direction.OUTGOING)
  .relationships(Rels.USED_IN, Direction.INCOMING)
  .relationships(Rels.MEMBER_OF, Direction.INCOMING)
  .relationships(Rels.COMPOSED_OF, Direction.OUTGOING)
  .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING)
  .evaluator(new Evaluator() {
     @Override
     public Evaluation evaluate(Path path) {
       if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){
           return Evaluation.INCLUDE_AND_PRUNE;
       }
        return Evaluation.EXCLUDE_AND_CONTINUE;
    }
  })
  .uniqueness(Uniqueness.NONE)
  .traverse(theDaleks);                        Relationships
Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle();

Traverser traverser = Traversal.description()
  .depthFirst()
  .relationships(Rels.APPEARED_IN, Direction.OUTGOING)
  .relationships(Rels.USED_IN, Direction.INCOMING)
  .relationships(Rels.MEMBER_OF, Direction.INCOMING)
  .relationships(Rels.COMPOSED_OF, Direction.OUTGOING)
  .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING)
  .evaluator(new Evaluator() {
     @Override
     public Evaluation evaluate(Path path) {
       if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){
           return Evaluation.INCLUDE_AND_PRUNE;
       }
        return Evaluation.EXCLUDE_AND_CONTINUE;
    }
  })
  .uniqueness(Uniqueness.NONE)
  .traverse(theDaleks);                            Evaluator
Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle();

Traverser traverser = Traversal.description()
  .depthFirst()
  .relationships(Rels.APPEARED_IN, Direction.OUTGOING)
  .relationships(Rels.USED_IN, Direction.INCOMING)
  .relationships(Rels.MEMBER_OF, Direction.INCOMING)
  .relationships(Rels.COMPOSED_OF, Direction.OUTGOING)
  .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING)
  .evaluator(new Evaluator() {
     @Override
     public Evaluation evaluate(Path path) {
       if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){
           return Evaluation.INCLUDE_AND_PRUNE;
       }
        return Evaluation.EXCLUDE_AND_CONTINUE;
    }
  })
  .uniqueness(Uniqueness.NONE)
  .traverse(theDaleks);                           Uniqueness
Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle();

Traverser traverser = Traversal.description()
  .depthFirst()
  .relationships(Rels.APPEARED_IN, Direction.OUTGOING)
  .relationships(Rels.USED_IN, Direction.INCOMING)
  .relationships(Rels.MEMBER_OF, Direction.INCOMING)
  .relationships(Rels.COMPOSED_OF, Direction.OUTGOING)
  .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING)
  .evaluator(new Evaluator() {
     @Override
     public Evaluation evaluate(Path path) {
       if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){
           return Evaluation.INCLUDE_AND_PRUNE;
       }
        return Evaluation.EXCLUDE_AND_CONTINUE;
    }
  })
  .uniqueness(Uniqueness.NONE)
  .traverse(theDaleks);                             Traverse
Iterable<Path>	
  
path.startNode()                                                                                                       path.endNode()
                       +tle:Power	
  of	
  	
  
  species:Dalek	
       the	
  Daleks	
              props:Daleks	
      name:Dalek	
  7	
            type:skirt	
        name:Dalek	
  7	
  



             APPEARED_IN	
                  USED_IN	
           MEMBER_OF	
           COMPOSED_OF	
            ORIGINAL_PROP	
  


                       +tle:Power	
  of	
  	
  
  species:Daleks	
      the	
  Daleks	
              props:Daleks	
       name:Dalek	
  7	
         type:shoulder	
        name:Dalek	
  7	
  



             APPEARED_IN	
                  USED_IN	
           MEMBER_OF	
           COMPOSED_OF	
            ORIGINAL_PROP	
  


                       +tle:Power	
  of	
  	
  
 species:Daleks	
       the	
  Daleks	
              props:Daleks	
     name:Dalek	
  Six-­‐5	
       type:skirt	
        name:Dalek	
  5	
  



             APPEARED_IN	
                  USED_IN	
           MEMBER_OF	
           COMPOSED_OF	
            ORIGINAL_PROP	
  
Cypher	
  
•  Declara+ve	
  graph	
  pa8ern	
  matching	
  language	
  
    –  Humane	
  regular	
  expressions	
  for	
  graphs	
  
•  New	
  in	
  1.4	
  
    –  Con+nuing,	
  rapid	
  feature	
  development	
  
•  Supports	
  queries	
  
    –  Including	
  aggrega+on,	
  ordering	
  and	
  limits	
  
    –  Muta+ng	
  opera+ons	
  coming	
  in	
  1.6	
  


                                                         #neo4j	
  
Cypher Query

start	
  daleks=node:species(species='Dalek')	
  	
  
match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  part-­‐[:ORIGINAL_PROP]-­‐>originalprop	
  
return	
  originalprop.name,	
  part.type,	
  count(episode.Qtle)	
  	
  
order	
  by	
  count(episode.Qtle)	
  desc	
  	
  
limit	
  1
Index Lookup

start	
  daleks=node:species(species='Dalek')	
  	
  
match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  part-­‐[:ORIGINAL_PROP]-­‐>originalprop	
  
return	
  originalprop.name,	
  part.type,	
  count(episode.Qtle)	
  	
  
order	
  by	
  count(episode.Qtle)	
  desc	
  	
  
limit	
  1
Match Nodes & Relationships

start	
  daleks=node:species(species='Dalek')	
  	
  
match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  part-­‐[:ORIGINAL_PROP]-­‐>originalprop	
  
return	
  originalprop.name,	
  part.type,	
  count(episode.Qtle)	
  	
  
order	
  by	
  count(episode.Qtle)	
  desc	
  	
  
limit	
  1
match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  part-­‐[:ORIGINAL_PROP]-­‐>originalprop	
  	
  

                                           APPEARED_IN	
  
                          daleks	
                                  episode	
  
                                                                                      USED_IN	
  


                                           MEMBER_OF	
  

                                                                                      COMPOSED_OF	
  


                                          ORIGINAL_PROP	
  
                           part	
                                  originalprop	
  
Return Values

start	
  daleks=node:species(species='Dalek')	
  	
  
match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  part-­‐[:ORIGINAL_PROP]-­‐>originalprop	
  
return	
  originalprop.name,	
  part.type,	
  count(episode.Qtle)	
  	
  
order	
  by	
  count(episode.Qtle)	
  desc	
  	
  
limit	
  1
In Code

CypherParser	
  parser	
  =	
  new	
  CypherParser();	
  
ExecuQonEngine	
  engine	
  =	
  new	
  ExecuQonEngine(universe.getDatabase());	
  
	
  	
  	
  
String	
  cql	
  =	
  "start	
  daleks=node:species(species='Dalek')"	
  
	
  	
  	
  	
  +	
  "	
  match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐()<-­‐[:MEMBER_OF]-­‐()"	
  
	
  	
  	
  	
  +	
  "-­‐[:COMPOSED_OF]-­‐>part-­‐[:ORIGINAL_PROP]-­‐>originalprop"	
  
	
  	
  	
  	
  +	
  "	
  return	
  originalprop.name,	
  part.type,	
  count(episode.Qtle)"	
  
	
  	
  	
  	
  +	
  "	
  order	
  by	
  count(episode.Qtle)	
  desc	
  limit	
  1";	
  
	
  
Query	
  query	
  =	
  parser.parse(cql);	
  
ExecuQonResult	
  result	
  =	
  engine.execute(query);	
  
	
  
String	
  originalProp	
  =	
  result.javaColumnAs("originalprop.name").next().toString();	
  
String	
  part	
  =	
  result.javaColumnAs("part.type").next().toString();	
  
int	
  episodeCount	
  =	
  (Integer)	
  result.javaColumnAs("count(episode.Qtle)").next();
Setup

CypherParser	
  parser	
  =	
  new	
  CypherParser();	
  
ExecuQonEngine	
  engine	
  =	
  new	
  ExecuQonEngine(universe.getDatabase());	
  
	
  	
  	
  
String	
  cql	
  =	
  "start	
  daleks=node:species(species='Dalek')"	
  
	
  	
  	
  	
  +	
  "	
  match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐()<-­‐[:MEMBER_OF]-­‐()"	
  
	
  	
  	
  	
  +	
  "-­‐[:COMPOSED_OF]-­‐>part-­‐[:ORIGINAL_PROP]-­‐>originalprop"	
  
	
  	
  	
  	
  +	
  "	
  return	
  originalprop.name,	
  part.type,	
  count(episode.Qtle)"	
  
	
  	
  	
  	
  +	
  "	
  order	
  by	
  count(episode.Qtle)	
  desc	
  limit	
  1";	
  
	
  
Query	
  query	
  =	
  parser.parse(cql);	
  
ExecuQonResult	
  result	
  =	
  engine.execute(query);	
  
	
  
String	
  originalProp	
  =	
  result.javaColumnAs("originalprop.name").next().toString();	
  
String	
  part	
  =	
  result.javaColumnAs("part.type").next().toString();	
  
int	
  episodeCount	
  =	
  (Integer)	
  result.javaColumnAs("count(episode.Qtle)").next();
Parse & Execute

CypherParser	
  parser	
  =	
  new	
  CypherParser();	
  
ExecuQonEngine	
  engine	
  =	
  new	
  ExecuQonEngine(universe.getDatabase());	
  
	
  	
  	
  
String	
  cql	
  =	
  "start	
  daleks=node:species(species='Dalek')"	
  
	
  	
  	
  	
  +	
  "	
  match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐()<-­‐[:MEMBER_OF]-­‐()"	
  
	
  	
  	
  	
  +	
  "-­‐[:COMPOSED_OF]-­‐>part-­‐[:ORIGINAL_PROP]-­‐>originalprop"	
  
	
  	
  	
  	
  +	
  "	
  return	
  originalprop.name,	
  part.type,	
  count(episode.Qtle)"	
  
	
  	
  	
  	
  +	
  "	
  order	
  by	
  count(episode.Qtle)	
  desc	
  limit	
  1";	
  
	
  
Query	
  query	
  =	
  parser.parse(cql);	
  
ExecuQonResult	
  result	
  =	
  engine.execute(query);	
  
	
  
String	
  originalProp	
  =	
  result.javaColumnAs("originalprop.name").next().toString();	
  
String	
  part	
  =	
  result.javaColumnAs("part.type").next().toString();	
  
int	
  episodeCount	
  =	
  (Integer)	
  result.javaColumnAs("count(episode.Qtle)").next();
Results

CypherParser	
  parser	
  =	
  new	
  CypherParser();	
  
ExecuQonEngine	
  engine	
  =	
  new	
  ExecuQonEngine(universe.getDatabase());	
  
	
  	
  	
  
String	
  cql	
  =	
  "start	
  daleks=node:species(species='Dalek')"	
  
	
  	
  	
  	
  +	
  "	
  match	
  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐()<-­‐[:MEMBER_OF]-­‐()"	
  
	
  	
  	
  	
  +	
  "-­‐[:COMPOSED_OF]-­‐>part-­‐[:ORIGINAL_PROP]-­‐>originalprop"	
  
	
  	
  	
  	
  +	
  "	
  return	
  originalprop.name,	
  part.type,	
  count(episode.Qtle)"	
  
	
  	
  	
  	
  +	
  "	
  order	
  by	
  count(episode.Qtle)	
  desc	
  limit	
  1";	
  
	
  
Query	
  query	
  =	
  parser.parse(cql);	
  
ExecuQonResult	
  result	
  =	
  engine.execute(query);	
  
	
  
String	
  originalProp	
  =	
  result.javaColumnAs("originalprop.name").next().toString();	
  
String	
  part	
  =	
  result.javaColumnAs("part.type").next().toString();	
  
int	
  episodeCount	
  =	
  (Integer)	
  result.javaColumnAs("count(episode.Qtle)").next();
In Webadmin
The	
  Hardest	
  Working	
  Prop	
  Part	
  
 Dalek	
  One’s	
  shoulders	
  




 hOp://www.dalek6388.co.uk/	
  
                                   #neo4j	
  
Download	
  
hOp://neo4j.org/download/	
  
	
  
	
  
	
  
hOp://www.springsource.org/
spring-­‐data/neo4j	
  
                          #neo4j	
  
Tutorial	
  




hOps://github.com/jimwebber/neo4j-­‐tutorial	
  

                                           #neo4j	
  
Dematerialize…        	
  

                 @iansrobinson	
  
ian.robinson@neotechnology.com	
  
                              	
  

                                            #neo4j	
  
1.    Subtract:	
  Select	
  rectangle	
  then	
  3	
  black	
  
      triangles	
  
2.    Union:	
  All	
  	
  
1.    Subtract:	
  Select	
  rectangle	
  then	
  3	
  black	
  
      triangles	
  
2.    Union:	
  All	
  	
  
1.    Subtract:	
  Select	
  rectangle	
  then	
  3	
  black	
  
      triangles	
  
2.    Union:	
  All	
  	
  
match	
  (daleks)-­‐[:APPEARED_IN]-­‐>(episode)<-­‐[:USED_IN]-­‐	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  (part)-­‐[:ORIGINAL_PROP]-­‐>(originalprop)	
  	
  

                                         APPEARED_IN	
  
                         daleks	
                                episode	
  
                                                                                   USED_IN	
  


                                         MEMBER_OF	
  

                                                                                   COMPOSED_OF	
  


                                        ORIGINAL_PROP	
  
                          part	
                                originalprop	
  

More Related Content

Viewers also liked

DevOps and Performance - Why, How and Best Practices - DevOps Meetup Sydney
DevOps and Performance - Why, How and Best Practices - DevOps Meetup SydneyDevOps and Performance - Why, How and Best Practices - DevOps Meetup Sydney
DevOps and Performance - Why, How and Best Practices - DevOps Meetup SydneyAndreas Grabner
 
ART1204 Art of the Ancient Near East
ART1204 Art of the Ancient Near EastART1204 Art of the Ancient Near East
ART1204 Art of the Ancient Near EastProfWillAdams
 
Background singers
Background singersBackground singers
Background singers13jkjordan
 
Hum2220 1330 art of the stone age
Hum2220 1330 art of the stone ageHum2220 1330 art of the stone age
Hum2220 1330 art of the stone ageProfWillAdams
 
Daily routines
Daily routinesDaily routines
Daily routinesDigna Rita
 
Java Tech & Tools | Grails in the Java Enterprise | Peter Ledbrook
Java Tech & Tools | Grails in the Java Enterprise | Peter LedbrookJava Tech & Tools | Grails in the Java Enterprise | Peter Ledbrook
Java Tech & Tools | Grails in the Java Enterprise | Peter LedbrookJAX London
 
Errol morris essay
Errol morris essayErrol morris essay
Errol morris essaypkirk63
 
гарчиггүй 1
гарчиггүй 1гарчиггүй 1
гарчиггүй 1mongoo_8301
 
2008 Spring Newsletter
2008 Spring Newsletter2008 Spring Newsletter
2008 Spring NewsletterDirect Relief
 
Tsunami response six months later
Tsunami response six months laterTsunami response six months later
Tsunami response six months laterDirect Relief
 
Hum2220 fa2014 syllabus
Hum2220 fa2014 syllabusHum2220 fa2014 syllabus
Hum2220 fa2014 syllabusProfWillAdams
 

Viewers also liked (18)

DevOps and Performance - Why, How and Best Practices - DevOps Meetup Sydney
DevOps and Performance - Why, How and Best Practices - DevOps Meetup SydneyDevOps and Performance - Why, How and Best Practices - DevOps Meetup Sydney
DevOps and Performance - Why, How and Best Practices - DevOps Meetup Sydney
 
ART1204 Art of the Ancient Near East
ART1204 Art of the Ancient Near EastART1204 Art of the Ancient Near East
ART1204 Art of the Ancient Near East
 
Mob home
Mob homeMob home
Mob home
 
Ojo ahumado
Ojo ahumadoOjo ahumado
Ojo ahumado
 
Background singers
Background singersBackground singers
Background singers
 
Hum2220 1330 art of the stone age
Hum2220 1330 art of the stone ageHum2220 1330 art of the stone age
Hum2220 1330 art of the stone age
 
аветов презентация 3.0
аветов презентация 3.0аветов презентация 3.0
аветов презентация 3.0
 
PROBLEM OF PSYCHOLOGY, Wundt
PROBLEM OF PSYCHOLOGY, WundtPROBLEM OF PSYCHOLOGY, Wundt
PROBLEM OF PSYCHOLOGY, Wundt
 
Daily routines
Daily routinesDaily routines
Daily routines
 
Turkey
TurkeyTurkey
Turkey
 
Java Tech & Tools | Grails in the Java Enterprise | Peter Ledbrook
Java Tech & Tools | Grails in the Java Enterprise | Peter LedbrookJava Tech & Tools | Grails in the Java Enterprise | Peter Ledbrook
Java Tech & Tools | Grails in the Java Enterprise | Peter Ledbrook
 
Errol morris essay
Errol morris essayErrol morris essay
Errol morris essay
 
гарчиггүй 1
гарчиггүй 1гарчиггүй 1
гарчиггүй 1
 
2008 Spring Newsletter
2008 Spring Newsletter2008 Spring Newsletter
2008 Spring Newsletter
 
Dataflow140711-a@Kernel/VM北陸1
Dataflow140711-a@Kernel/VM北陸1Dataflow140711-a@Kernel/VM北陸1
Dataflow140711-a@Kernel/VM北陸1
 
Fall newsletter-2009
Fall newsletter-2009Fall newsletter-2009
Fall newsletter-2009
 
Tsunami response six months later
Tsunami response six months laterTsunami response six months later
Tsunami response six months later
 
Hum2220 fa2014 syllabus
Hum2220 fa2014 syllabusHum2220 fa2014 syllabus
Hum2220 fa2014 syllabus
 

More from JAX London

Java Tech & Tools | Continuous Delivery - the Writing is on the Wall | John S...
Java Tech & Tools | Continuous Delivery - the Writing is on the Wall | John S...Java Tech & Tools | Continuous Delivery - the Writing is on the Wall | John S...
Java Tech & Tools | Continuous Delivery - the Writing is on the Wall | John S...JAX London
 
Java Tech & Tools | Mapping, GIS and Geolocating Data in Java | Joachim Van d...
Java Tech & Tools | Mapping, GIS and Geolocating Data in Java | Joachim Van d...Java Tech & Tools | Mapping, GIS and Geolocating Data in Java | Joachim Van d...
Java Tech & Tools | Mapping, GIS and Geolocating Data in Java | Joachim Van d...JAX London
 
Keynote | Middleware Everywhere - Ready for Mobile and Cloud | Dr. Mark Little
Keynote | Middleware Everywhere - Ready for Mobile and Cloud | Dr. Mark LittleKeynote | Middleware Everywhere - Ready for Mobile and Cloud | Dr. Mark Little
Keynote | Middleware Everywhere - Ready for Mobile and Cloud | Dr. Mark LittleJAX London
 
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...JAX London
 
Spring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Day | Behind the Scenes at Spring Batch | Dave SyerSpring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Day | Behind the Scenes at Spring Batch | Dave SyerJAX London
 
Spring Day | Spring 3.1 in a Nutshell | Sam Brannen
Spring Day | Spring 3.1 in a Nutshell | Sam BrannenSpring Day | Spring 3.1 in a Nutshell | Sam Brannen
Spring Day | Spring 3.1 in a Nutshell | Sam BrannenJAX London
 
Spring Day | Identity Management with Spring Security | Dave Syer
Spring Day | Identity Management with Spring Security | Dave SyerSpring Day | Identity Management with Spring Security | Dave Syer
Spring Day | Identity Management with Spring Security | Dave SyerJAX London
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffJAX London
 
Spring Day | Data Access 2.0? Please Welcome Spring Data! | Oliver Gierke
Spring Day | Data Access 2.0? Please Welcome Spring Data! | Oliver GierkeSpring Day | Data Access 2.0? Please Welcome Spring Data! | Oliver Gierke
Spring Day | Data Access 2.0? Please Welcome Spring Data! | Oliver GierkeJAX London
 
Keynote | The Rise and Fall and Rise of Java | James Governor
Keynote | The Rise and Fall and Rise of Java | James GovernorKeynote | The Rise and Fall and Rise of Java | James Governor
Keynote | The Rise and Fall and Rise of Java | James GovernorJAX London
 
Java Tech & Tools | OSGi Best Practices | Emily Jiang
Java Tech & Tools | OSGi Best Practices | Emily JiangJava Tech & Tools | OSGi Best Practices | Emily Jiang
Java Tech & Tools | OSGi Best Practices | Emily JiangJAX London
 
Java Tech & Tools | Beyond the Data Grid: Coherence, Normalisation, Joins and...
Java Tech & Tools | Beyond the Data Grid: Coherence, Normalisation, Joins and...Java Tech & Tools | Beyond the Data Grid: Coherence, Normalisation, Joins and...
Java Tech & Tools | Beyond the Data Grid: Coherence, Normalisation, Joins and...JAX London
 
Java Tech & Tools | Big Blobs: Moving Big Data In and Out of the Cloud | Adri...
Java Tech & Tools | Big Blobs: Moving Big Data In and Out of the Cloud | Adri...Java Tech & Tools | Big Blobs: Moving Big Data In and Out of the Cloud | Adri...
Java Tech & Tools | Big Blobs: Moving Big Data In and Out of the Cloud | Adri...JAX London
 
Java Tech & Tools | Social Media in Programming in Java | Khanderao Kand
Java Tech & Tools | Social Media in Programming in Java | Khanderao KandJava Tech & Tools | Social Media in Programming in Java | Khanderao Kand
Java Tech & Tools | Social Media in Programming in Java | Khanderao KandJAX London
 
Java Tech & Tools | Just Keep Passing the Message | Russel Winder
Java Tech & Tools | Just Keep Passing the Message | Russel WinderJava Tech & Tools | Just Keep Passing the Message | Russel Winder
Java Tech & Tools | Just Keep Passing the Message | Russel WinderJAX London
 
Java Tech & Tools | Deploying Java & Play Framework Apps to the Cloud | Sande...
Java Tech & Tools | Deploying Java & Play Framework Apps to the Cloud | Sande...Java Tech & Tools | Deploying Java & Play Framework Apps to the Cloud | Sande...
Java Tech & Tools | Deploying Java & Play Framework Apps to the Cloud | Sande...JAX London
 
Java EE | Modular EJBs for Enterprise OSGi | Tim Ward
Java EE | Modular EJBs for Enterprise OSGi | Tim WardJava EE | Modular EJBs for Enterprise OSGi | Tim Ward
Java EE | Modular EJBs for Enterprise OSGi | Tim WardJAX London
 
Java EE | Apache TomEE - Java EE Web Profile on Tomcat | Jonathan Gallimore
Java EE | Apache TomEE - Java EE Web Profile on Tomcat | Jonathan GallimoreJava EE | Apache TomEE - Java EE Web Profile on Tomcat | Jonathan Gallimore
Java EE | Apache TomEE - Java EE Web Profile on Tomcat | Jonathan GallimoreJAX London
 
Java Core | Understanding the Disruptor: a Beginner's Guide to Hardcore Concu...
Java Core | Understanding the Disruptor: a Beginner's Guide to Hardcore Concu...Java Core | Understanding the Disruptor: a Beginner's Guide to Hardcore Concu...
Java Core | Understanding the Disruptor: a Beginner's Guide to Hardcore Concu...JAX London
 
Java Core | Java 8 and OSGi Modularisation | Tim Ellison & Neil Bartlett
Java Core | Java 8 and OSGi Modularisation | Tim Ellison & Neil BartlettJava Core | Java 8 and OSGi Modularisation | Tim Ellison & Neil Bartlett
Java Core | Java 8 and OSGi Modularisation | Tim Ellison & Neil BartlettJAX London
 

More from JAX London (20)

Java Tech & Tools | Continuous Delivery - the Writing is on the Wall | John S...
Java Tech & Tools | Continuous Delivery - the Writing is on the Wall | John S...Java Tech & Tools | Continuous Delivery - the Writing is on the Wall | John S...
Java Tech & Tools | Continuous Delivery - the Writing is on the Wall | John S...
 
Java Tech & Tools | Mapping, GIS and Geolocating Data in Java | Joachim Van d...
Java Tech & Tools | Mapping, GIS and Geolocating Data in Java | Joachim Van d...Java Tech & Tools | Mapping, GIS and Geolocating Data in Java | Joachim Van d...
Java Tech & Tools | Mapping, GIS and Geolocating Data in Java | Joachim Van d...
 
Keynote | Middleware Everywhere - Ready for Mobile and Cloud | Dr. Mark Little
Keynote | Middleware Everywhere - Ready for Mobile and Cloud | Dr. Mark LittleKeynote | Middleware Everywhere - Ready for Mobile and Cloud | Dr. Mark Little
Keynote | Middleware Everywhere - Ready for Mobile and Cloud | Dr. Mark Little
 
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
 
Spring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Day | Behind the Scenes at Spring Batch | Dave SyerSpring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Day | Behind the Scenes at Spring Batch | Dave Syer
 
Spring Day | Spring 3.1 in a Nutshell | Sam Brannen
Spring Day | Spring 3.1 in a Nutshell | Sam BrannenSpring Day | Spring 3.1 in a Nutshell | Sam Brannen
Spring Day | Spring 3.1 in a Nutshell | Sam Brannen
 
Spring Day | Identity Management with Spring Security | Dave Syer
Spring Day | Identity Management with Spring Security | Dave SyerSpring Day | Identity Management with Spring Security | Dave Syer
Spring Day | Identity Management with Spring Security | Dave Syer
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
 
Spring Day | Data Access 2.0? Please Welcome Spring Data! | Oliver Gierke
Spring Day | Data Access 2.0? Please Welcome Spring Data! | Oliver GierkeSpring Day | Data Access 2.0? Please Welcome Spring Data! | Oliver Gierke
Spring Day | Data Access 2.0? Please Welcome Spring Data! | Oliver Gierke
 
Keynote | The Rise and Fall and Rise of Java | James Governor
Keynote | The Rise and Fall and Rise of Java | James GovernorKeynote | The Rise and Fall and Rise of Java | James Governor
Keynote | The Rise and Fall and Rise of Java | James Governor
 
Java Tech & Tools | OSGi Best Practices | Emily Jiang
Java Tech & Tools | OSGi Best Practices | Emily JiangJava Tech & Tools | OSGi Best Practices | Emily Jiang
Java Tech & Tools | OSGi Best Practices | Emily Jiang
 
Java Tech & Tools | Beyond the Data Grid: Coherence, Normalisation, Joins and...
Java Tech & Tools | Beyond the Data Grid: Coherence, Normalisation, Joins and...Java Tech & Tools | Beyond the Data Grid: Coherence, Normalisation, Joins and...
Java Tech & Tools | Beyond the Data Grid: Coherence, Normalisation, Joins and...
 
Java Tech & Tools | Big Blobs: Moving Big Data In and Out of the Cloud | Adri...
Java Tech & Tools | Big Blobs: Moving Big Data In and Out of the Cloud | Adri...Java Tech & Tools | Big Blobs: Moving Big Data In and Out of the Cloud | Adri...
Java Tech & Tools | Big Blobs: Moving Big Data In and Out of the Cloud | Adri...
 
Java Tech & Tools | Social Media in Programming in Java | Khanderao Kand
Java Tech & Tools | Social Media in Programming in Java | Khanderao KandJava Tech & Tools | Social Media in Programming in Java | Khanderao Kand
Java Tech & Tools | Social Media in Programming in Java | Khanderao Kand
 
Java Tech & Tools | Just Keep Passing the Message | Russel Winder
Java Tech & Tools | Just Keep Passing the Message | Russel WinderJava Tech & Tools | Just Keep Passing the Message | Russel Winder
Java Tech & Tools | Just Keep Passing the Message | Russel Winder
 
Java Tech & Tools | Deploying Java & Play Framework Apps to the Cloud | Sande...
Java Tech & Tools | Deploying Java & Play Framework Apps to the Cloud | Sande...Java Tech & Tools | Deploying Java & Play Framework Apps to the Cloud | Sande...
Java Tech & Tools | Deploying Java & Play Framework Apps to the Cloud | Sande...
 
Java EE | Modular EJBs for Enterprise OSGi | Tim Ward
Java EE | Modular EJBs for Enterprise OSGi | Tim WardJava EE | Modular EJBs for Enterprise OSGi | Tim Ward
Java EE | Modular EJBs for Enterprise OSGi | Tim Ward
 
Java EE | Apache TomEE - Java EE Web Profile on Tomcat | Jonathan Gallimore
Java EE | Apache TomEE - Java EE Web Profile on Tomcat | Jonathan GallimoreJava EE | Apache TomEE - Java EE Web Profile on Tomcat | Jonathan Gallimore
Java EE | Apache TomEE - Java EE Web Profile on Tomcat | Jonathan Gallimore
 
Java Core | Understanding the Disruptor: a Beginner's Guide to Hardcore Concu...
Java Core | Understanding the Disruptor: a Beginner's Guide to Hardcore Concu...Java Core | Understanding the Disruptor: a Beginner's Guide to Hardcore Concu...
Java Core | Understanding the Disruptor: a Beginner's Guide to Hardcore Concu...
 
Java Core | Java 8 and OSGi Modularisation | Tim Ellison & Neil Bartlett
Java Core | Java 8 and OSGi Modularisation | Tim Ellison & Neil BartlettJava Core | Java 8 and OSGi Modularisation | Tim Ellison & Neil Bartlett
Java Core | Java 8 and OSGi Modularisation | Tim Ellison & Neil Bartlett
 

Recently uploaded

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

Big Data & Cloud | An Introduction to Neo4j (and Doctor Who) | Ian Robinson

  • 1. An  Introduc+on  to  Doctor  Who   (and  Neo4j)     @iansrobinson   #neo4j  
  • 2. Neo4j  is  a  Graph  Database   #neo4j  
  • 5. Neo4j   #neo4j  
  • 7. 32  billion  nodes   32  billion  rela+onships   64  billion  proper+es  
  • 9. Community   Advanced   Enterprise  
  • 10. stole   companion   from   loves   loves   appeared     enemy   in   companion   appeared     in   appeared     in   enemy   enemy   appeared     appeared     A  Good  Man   in   in   Goes  to  War   Victory  of     the  Daleks   appeared     in  
  • 11. GraphDatabaseService db = new EmbeddedGraphDatabase("/data/drwho");
  • 12. GraphDatabaseService db = new EmbeddedGraphDatabase("/data/drwho"); Node theDoctor = db.createNode(); theDoctor.setProperty("name", "The Doctor"); Node daleks = db.createNode(); daleks.setProperty("name", "Daleks"); Node cybermen = db.createNode(); cybermen.setProperty("name", "Cybermen");
  • 13. GraphDatabaseService db = new EmbeddedGraphDatabase("/data/drwho"); Node theDoctor = db.createNode(); enemy   theDoctor.setProperty("name", "The Doctor"); Node daleks = db.createNode(); daleks.setProperty("name", "Daleks"); Node cybermen = db.createNode(); cybermen.setProperty("name", "Cybermen"); enemy   theDoctor.createRelationshipTo(daleks, DynamicRelationshipType.withName("enemy")); theDoctor.createRelationshipTo(cybermen, DynamicRelationshipType.withName("enemy"));
  • 14. GraphDatabaseService db = new EmbeddedGraphDatabase("/data/drwho"); Transaction tx = db.beginTx(); try { Node theDoctor = db.createNode(); enemy   theDoctor.setProperty("name", "The Doctor"); Node daleks = db.createNode(); daleks.setProperty("name", "Daleks"); Node cybermen = db.createNode(); cybermen.setProperty("name", "Cybermen"); enemy   theDoctor.createRelationshipTo(daleks, DynamicRelationshipType.withName("enemy")); theDoctor.createRelationshipTo(cybermen, DynamicRelationshipType.withName("enemy")); tx.success(); } finally { tx.finish(); }
  • 15. How  do  I  query  the  data?   hOp://opfm.jpl.nasa.gov/   hOp://news.xinhuanet.com   #neo4j  
  • 16. Dalek  Props   hOp://www.dalek6388.co.uk/   #neo4j  
  • 17. species:Dalek   APPEARED_IN   !tle:Power  of     the  Daleks   USED_IN   props:Daleks   MEMBER_OF   MEMBER_OF   name:Dalek  Six-­‐5   name:Dalek  1   name:Dalek  2   name:Dalek  7   type:shoulders   type:skirt  
  • 18. name:Dalek  1   name:Dalek  2   name:Dalek  7   name:Dalek  Six-­‐5   ORIGINAL_PROP   ORIGINAL_PROP   ORIGINAL_PROP   ORIGINAL_PROP   name:Dalek  6   name:Dalek  5  
  • 19. !tle:The   !tle:Power  of     !tle:The   Dalek   the  Daleks   Daleks   Invasion  of   Earth   name:   name:Dalek  1   name:Dalek  2   name:Dalek  7   Dalek  Six-­‐5   name:Dalek  Two-­‐1   name:Dalek  One-­‐5   name:Dalek  Six-­‐7  
  • 21. Traversal  Framework   •  Visits  (and  returns)  nodes  based  on  traversal   descrip+on   •  Powerful;  can  customize:   –  Rela+onships  followed   –  Branch  selec+on  policy   –  Node/rela+onship  uniqueness  constraints   –  Path  evaluators   #neo4j  
  • 22. Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle(); Traverser traverser = Traversal.description() .depthFirst() .relationships(Rels.APPEARED_IN, Direction.OUTGOING) .relationships(Rels.USED_IN, Direction.INCOMING) .relationships(Rels.MEMBER_OF, Direction.INCOMING) .relationships(Rels.COMPOSED_OF, Direction.OUTGOING) .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING) .evaluator(new Evaluator() { @Override public Evaluation evaluate(Path path) { if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){ return Evaluation.INCLUDE_AND_PRUNE; } return Evaluation.EXCLUDE_AND_CONTINUE; } }) .uniqueness(Uniqueness.NONE) .traverse(theDaleks); Description
  • 23. Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle(); Traverser traverser = Traversal.description() .depthFirst() .relationships(Rels.APPEARED_IN, Direction.OUTGOING) .relationships(Rels.USED_IN, Direction.INCOMING) .relationships(Rels.MEMBER_OF, Direction.INCOMING) .relationships(Rels.COMPOSED_OF, Direction.OUTGOING) .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING) .evaluator(new Evaluator() { @Override public Evaluation evaluate(Path path) { if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){ return Evaluation.INCLUDE_AND_PRUNE; } return Evaluation.EXCLUDE_AND_CONTINUE; } }) .uniqueness(Uniqueness.NONE) .traverse(theDaleks); Index Lookup
  • 24. Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle(); Traverser traverser = Traversal.description() .depthFirst() .relationships(Rels.APPEARED_IN, Direction.OUTGOING) .relationships(Rels.USED_IN, Direction.INCOMING) .relationships(Rels.MEMBER_OF, Direction.INCOMING) .relationships(Rels.COMPOSED_OF, Direction.OUTGOING) .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING) .evaluator(new Evaluator() { @Override public Evaluation evaluate(Path path) { if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){ return Evaluation.INCLUDE_AND_PRUNE; } return Evaluation.EXCLUDE_AND_CONTINUE; } }) .uniqueness(Uniqueness.NONE) .traverse(theDaleks); Branching
  • 25. Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle(); Traverser traverser = Traversal.description() .depthFirst() .relationships(Rels.APPEARED_IN, Direction.OUTGOING) .relationships(Rels.USED_IN, Direction.INCOMING) .relationships(Rels.MEMBER_OF, Direction.INCOMING) .relationships(Rels.COMPOSED_OF, Direction.OUTGOING) .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING) .evaluator(new Evaluator() { @Override public Evaluation evaluate(Path path) { if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){ return Evaluation.INCLUDE_AND_PRUNE; } return Evaluation.EXCLUDE_AND_CONTINUE; } }) .uniqueness(Uniqueness.NONE) .traverse(theDaleks); Relationships
  • 26. Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle(); Traverser traverser = Traversal.description() .depthFirst() .relationships(Rels.APPEARED_IN, Direction.OUTGOING) .relationships(Rels.USED_IN, Direction.INCOMING) .relationships(Rels.MEMBER_OF, Direction.INCOMING) .relationships(Rels.COMPOSED_OF, Direction.OUTGOING) .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING) .evaluator(new Evaluator() { @Override public Evaluation evaluate(Path path) { if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){ return Evaluation.INCLUDE_AND_PRUNE; } return Evaluation.EXCLUDE_AND_CONTINUE; } }) .uniqueness(Uniqueness.NONE) .traverse(theDaleks); Evaluator
  • 27. Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle(); Traverser traverser = Traversal.description() .depthFirst() .relationships(Rels.APPEARED_IN, Direction.OUTGOING) .relationships(Rels.USED_IN, Direction.INCOMING) .relationships(Rels.MEMBER_OF, Direction.INCOMING) .relationships(Rels.COMPOSED_OF, Direction.OUTGOING) .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING) .evaluator(new Evaluator() { @Override public Evaluation evaluate(Path path) { if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){ return Evaluation.INCLUDE_AND_PRUNE; } return Evaluation.EXCLUDE_AND_CONTINUE; } }) .uniqueness(Uniqueness.NONE) .traverse(theDaleks); Uniqueness
  • 28. Node theDaleks = database.index().forNodes("species").get("name", "Dalek").getSingle(); Traverser traverser = Traversal.description() .depthFirst() .relationships(Rels.APPEARED_IN, Direction.OUTGOING) .relationships(Rels.USED_IN, Direction.INCOMING) .relationships(Rels.MEMBER_OF, Direction.INCOMING) .relationships(Rels.COMPOSED_OF, Direction.OUTGOING) .relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING) .evaluator(new Evaluator() { @Override public Evaluation evaluate(Path path) { if (path.lastRelationship() != null && path.lastRelationship().isType(Rels.ORIGINAL_PROP)){ return Evaluation.INCLUDE_AND_PRUNE; } return Evaluation.EXCLUDE_AND_CONTINUE; } }) .uniqueness(Uniqueness.NONE) .traverse(theDaleks); Traverse
  • 29. Iterable<Path>   path.startNode() path.endNode() +tle:Power  of     species:Dalek   the  Daleks   props:Daleks   name:Dalek  7   type:skirt   name:Dalek  7   APPEARED_IN   USED_IN   MEMBER_OF   COMPOSED_OF   ORIGINAL_PROP   +tle:Power  of     species:Daleks   the  Daleks   props:Daleks   name:Dalek  7   type:shoulder   name:Dalek  7   APPEARED_IN   USED_IN   MEMBER_OF   COMPOSED_OF   ORIGINAL_PROP   +tle:Power  of     species:Daleks   the  Daleks   props:Daleks   name:Dalek  Six-­‐5   type:skirt   name:Dalek  5   APPEARED_IN   USED_IN   MEMBER_OF   COMPOSED_OF   ORIGINAL_PROP  
  • 30. Cypher   •  Declara+ve  graph  pa8ern  matching  language   –  Humane  regular  expressions  for  graphs   •  New  in  1.4   –  Con+nuing,  rapid  feature  development   •  Supports  queries   –  Including  aggrega+on,  ordering  and  limits   –  Muta+ng  opera+ons  coming  in  1.6   #neo4j  
  • 31. Cypher Query start  daleks=node:species(species='Dalek')     match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐                          ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>                            part-­‐[:ORIGINAL_PROP]-­‐>originalprop   return  originalprop.name,  part.type,  count(episode.Qtle)     order  by  count(episode.Qtle)  desc     limit  1
  • 32. Index Lookup start  daleks=node:species(species='Dalek')     match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐                          ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>                            part-­‐[:ORIGINAL_PROP]-­‐>originalprop   return  originalprop.name,  part.type,  count(episode.Qtle)     order  by  count(episode.Qtle)  desc     limit  1
  • 33. Match Nodes & Relationships start  daleks=node:species(species='Dalek')     match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐                          ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>                            part-­‐[:ORIGINAL_PROP]-­‐>originalprop   return  originalprop.name,  part.type,  count(episode.Qtle)     order  by  count(episode.Qtle)  desc     limit  1
  • 34. match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐                          ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>                            part-­‐[:ORIGINAL_PROP]-­‐>originalprop     APPEARED_IN   daleks   episode   USED_IN   MEMBER_OF   COMPOSED_OF   ORIGINAL_PROP   part   originalprop  
  • 35. Return Values start  daleks=node:species(species='Dalek')     match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐                          ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>                            part-­‐[:ORIGINAL_PROP]-­‐>originalprop   return  originalprop.name,  part.type,  count(episode.Qtle)     order  by  count(episode.Qtle)  desc     limit  1
  • 36. In Code CypherParser  parser  =  new  CypherParser();   ExecuQonEngine  engine  =  new  ExecuQonEngine(universe.getDatabase());         String  cql  =  "start  daleks=node:species(species='Dalek')"          +  "  match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐()<-­‐[:MEMBER_OF]-­‐()"          +  "-­‐[:COMPOSED_OF]-­‐>part-­‐[:ORIGINAL_PROP]-­‐>originalprop"          +  "  return  originalprop.name,  part.type,  count(episode.Qtle)"          +  "  order  by  count(episode.Qtle)  desc  limit  1";     Query  query  =  parser.parse(cql);   ExecuQonResult  result  =  engine.execute(query);     String  originalProp  =  result.javaColumnAs("originalprop.name").next().toString();   String  part  =  result.javaColumnAs("part.type").next().toString();   int  episodeCount  =  (Integer)  result.javaColumnAs("count(episode.Qtle)").next();
  • 37. Setup CypherParser  parser  =  new  CypherParser();   ExecuQonEngine  engine  =  new  ExecuQonEngine(universe.getDatabase());         String  cql  =  "start  daleks=node:species(species='Dalek')"          +  "  match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐()<-­‐[:MEMBER_OF]-­‐()"          +  "-­‐[:COMPOSED_OF]-­‐>part-­‐[:ORIGINAL_PROP]-­‐>originalprop"          +  "  return  originalprop.name,  part.type,  count(episode.Qtle)"          +  "  order  by  count(episode.Qtle)  desc  limit  1";     Query  query  =  parser.parse(cql);   ExecuQonResult  result  =  engine.execute(query);     String  originalProp  =  result.javaColumnAs("originalprop.name").next().toString();   String  part  =  result.javaColumnAs("part.type").next().toString();   int  episodeCount  =  (Integer)  result.javaColumnAs("count(episode.Qtle)").next();
  • 38. Parse & Execute CypherParser  parser  =  new  CypherParser();   ExecuQonEngine  engine  =  new  ExecuQonEngine(universe.getDatabase());         String  cql  =  "start  daleks=node:species(species='Dalek')"          +  "  match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐()<-­‐[:MEMBER_OF]-­‐()"          +  "-­‐[:COMPOSED_OF]-­‐>part-­‐[:ORIGINAL_PROP]-­‐>originalprop"          +  "  return  originalprop.name,  part.type,  count(episode.Qtle)"          +  "  order  by  count(episode.Qtle)  desc  limit  1";     Query  query  =  parser.parse(cql);   ExecuQonResult  result  =  engine.execute(query);     String  originalProp  =  result.javaColumnAs("originalprop.name").next().toString();   String  part  =  result.javaColumnAs("part.type").next().toString();   int  episodeCount  =  (Integer)  result.javaColumnAs("count(episode.Qtle)").next();
  • 39. Results CypherParser  parser  =  new  CypherParser();   ExecuQonEngine  engine  =  new  ExecuQonEngine(universe.getDatabase());         String  cql  =  "start  daleks=node:species(species='Dalek')"          +  "  match  daleks-­‐[:APPEARED_IN]-­‐>episode<-­‐[:USED_IN]-­‐()<-­‐[:MEMBER_OF]-­‐()"          +  "-­‐[:COMPOSED_OF]-­‐>part-­‐[:ORIGINAL_PROP]-­‐>originalprop"          +  "  return  originalprop.name,  part.type,  count(episode.Qtle)"          +  "  order  by  count(episode.Qtle)  desc  limit  1";     Query  query  =  parser.parse(cql);   ExecuQonResult  result  =  engine.execute(query);     String  originalProp  =  result.javaColumnAs("originalprop.name").next().toString();   String  part  =  result.javaColumnAs("part.type").next().toString();   int  episodeCount  =  (Integer)  result.javaColumnAs("count(episode.Qtle)").next();
  • 41. The  Hardest  Working  Prop  Part   Dalek  One’s  shoulders   hOp://www.dalek6388.co.uk/   #neo4j  
  • 42. Download   hOp://neo4j.org/download/         hOp://www.springsource.org/ spring-­‐data/neo4j   #neo4j  
  • 44. Dematerialize…   @iansrobinson   ian.robinson@neotechnology.com     #neo4j  
  • 45. 1.  Subtract:  Select  rectangle  then  3  black   triangles   2.  Union:  All    
  • 46. 1.  Subtract:  Select  rectangle  then  3  black   triangles   2.  Union:  All    
  • 47. 1.  Subtract:  Select  rectangle  then  3  black   triangles   2.  Union:  All    
  • 48. match  (daleks)-­‐[:APPEARED_IN]-­‐>(episode)<-­‐[:USED_IN]-­‐                          ()<-­‐[:MEMBER_OF]-­‐()-­‐[:COMPOSED_OF]-­‐>                            (part)-­‐[:ORIGINAL_PROP]-­‐>(originalprop)     APPEARED_IN   daleks   episode   USED_IN   MEMBER_OF   COMPOSED_OF   ORIGINAL_PROP   part   originalprop