Preview

This graph is used to visualize the knowledge a person has in a certain area. In this example, the knowledge a Java developer has over a stack of technologies. The purpose is to document acquired knowledge and to help to further educate oneself in a structured way. This is accomplished by graphing dependencies between technologies as well as resources that can be used to learn a technology and to determine possible 'learning paths' through the graph, which show a way to learn a specific technology, by first learning the technologies, in order, which are prerequisites for the technology to be learned. The graph is meant not to be static, but updated as new connections between technologies are discovered and new knowledge is acquired.

The main use case explored here is how to learn Spring Data Neo4j (SDN) in a structured manner.

Node types

  • Person: green

  • Technology: yellow

  • Concept: orange

  • Resources: blue

Notes

  • The console is at the bottom of the page, after clicking the 'Play/Edit in console' button, you have to scroll down manually.

  • Graph images have been created from GraphML files, edited and exported from Yed.

The initial graph

//// Create nodes

// Technologies
CREATE
  (java:Tech { name:"Java" }),
  (spring:Tech { name:"Spring" }),
  (neo4j:Tech { name:"Neo4j" }),
  (springDataNeo4j:Tech { name:"Spring Data Neo4j" })

// Concepts
CREATE
  (dependencyInjection:Concept { name:"Dependency Injection" })

// Resources
CREATE
  (hfj:Book { name:"Head First Java" }),
  (effectiveJava:Book { name:"Effective Java", level:"ADVANCED" }),
  (neo4jTutorial:Tutorial { name:"Neo4j Tutorial" }),
  (neo4jDocs:Manual { name:"Neo4j Reference Documentation" }),
  (neo4jInAction:Book { name:"Neo4j in Action" }),
  (springData:Book { name:"Spring Data" })

// People
CREATE
  (javaDev:Person { name:"Java Developer" }),
  (springExpert:Person { name:"Spring Expert" })


//// Relate nodes

// Dependencies
CREATE
  (springDataNeo4j)-[:REQUIRES]->(spring),
  (springDataNeo4j)-[:REQUIRES]->(neo4j),
  (spring)-[:REQUIRES]->(java),
  (spring)-[:REQUIRES]->(dependencyInjection)

// Existing knowledge
CREATE
  (javaDev)-[:UNDERSTANDS { since:2013, level:"BASIC" }]->(java),
  (javaDev)-[:UNDERSTANDS { level:"BASIC" }]->(dependencyInjection),
  (springExpert)-[:UNDERSTANDS { since:2005 }]->(java),
  (springExpert)-[:UNDERSTANDS { since:2008 }]->(dependencyInjection),
  (springExpert)-[:UNDERSTANDS { since:2009, level:"EXPERT" }]->(spring)

// Paths to knowledge
CREATE
  (hfj)-[:TEACHES { level:"BASIC" }]->(java),
  (effectiveJava)-[:TEACHES { level:"ADVANCED" }]->(java),
  (neo4jTutorial)-[:TEACHES { level:"BASIC" }]->(neo4j),
  (neo4jDocs)-[:TEACHES]->(neo4j),
  (neo4jInAction)-[:TEACHES]->(neo4j),
  (springData)-[:TEACHES]->(springDataNeo4j)

Lets see what can be done this with data …​

MATCH p=(sdn:Tech {name:"Spring Data Neo4j"})-[:REQUIRES*]->(required)
RETURN last(nodes(p)).name AS `Technology or concept`, length(p) AS `Steps to SDN`
ORDER BY `Steps to SDN` DESC
Loading table...

What does the Java Developer know already?

MATCH (javaDev:Person {name:"Java Developer"})-[:UNDERSTANDS]->(tech)
RETURN tech.name AS `Technology or concept`
Loading table...

Which resources can be used to get an overview of the technologies?

This query favors resources with a basic (or beginner) level to allow to quickly learn about the technologies, what they consist of, how much time they might need to learn etc, without going too much into detail or actually using the technology.

MATCH (sdn:Tech {name:"Spring Data Neo4j"}),
      p=(sdn)-[:REQUIRES*0..]->(technology:Tech)<-[teaches:TEACHES]-(resource)
WHERE not(has(teaches.level)) OR teaches.level = "BASIC"
RETURN collect(resource.name) AS Resource, technology.name AS Technology,
       length(p) AS `Steps to SDN`
ORDER BY `Steps to SDN` DESC
Loading table...

Now, having a good overview of the technologies, the understanding - as represented by the graph - can be extended. E.g. it is now known that SDN has two modes and that SDN requires understanding of the Repository Pattern. Furthermore it was learned that Aspect-Oriented Programming is a concept that is a part of Spring (but not a requirement for Spring, nor SDN, as it is optional).

Add newly acquired knowledge about technology relations to the graph

MATCH (sdn:Tech {name:"Spring Data Neo4j"}),
      (springData:Book {name:"Spring Data"}),
      (spring:Tech {name:"Spring"})
CREATE
  (sdn)-[:REQUIRES]->(repositoryPattern:Concept {name: "Repository Pattern"}),
  (springData)-[:TEACHES]->(repositoryPattern),
  (simpleMode:Tech {name:"Simple Mapping Mode"})-[:PART_OF]->(sdn),
  (advancedMode:Tech {name:"Advanced Mapping Mode"})-[:PART_OF]->(sdn),
  (simpleMode)-[:ALTERNATIVE_TO]->(advancedMode),
  (advancedMode)-[:ALTERNATIVE_TO]->(simpleMode),
  (eval:Evaluation {name:"SDN Modes Evaluation"})-[:REJECTED]->(simpleMode),
  (eval)-[:ACCEPTED]->(advancedMode),
  (spring)-[:PART_OF]->(aop:Concept {name:"Aspect-Oriented Programming"})

Additionally, while learning about SDN, an Evaluation of the modes was done and a decision was made to use the advanced mapping mode, which was documented by the newly created Evaluation node.

The graph would then look like this (new nodes are displayed with an ellipse shape)

Even further, an evaluation of the modes depends on whether an embedded database or a remote database is used, which should be decided on a per-project basis. So the project could be modeled in the graph too, get connected to the evaluation node and then, of course, get connected to the technologies the project uses. Then we can ask the graph further questions, like "Which projects has the Java Developer worked on and which technologies has he used during?". Not only that, but by adding all team members to the graph, required learning for the project could be managed by looking at what each developer knows already, who could learn a needed technology the fastest based on existing knowledge etc. As this example is about learning, modeling projects and teams is something for another example.

Coming back to what was just learned, the fact that Spring uses Aspect-Oriented Programming was learned rather by accident, through a Google search. There is no resource to learn Spring in the graph! This can’t be good. Are there any more cases like this?

MATCH (techOrConcept)
WHERE NOT (techOrConcept)<-[:TEACHES]-()
  AND (techOrConcept:Tech OR techOrConcept:Concept)
RETURN techOrConcept.name AS `Technology or concept`
Loading table...

There is indeed no resource for learning Spring. Nor for Dependency Injection or SDNs modes. That’s okay for the Java Developer though, as he knows Dependency Injection, and the modes are a part of SDN, so they’re explained in the Spring Data book. For Spring itself, the developer should look for a suitable book and add it to the graph. A book on Spring would also touch on Aspect-Oriented Programming and either explain it, or reference other resources that could be used to learn it.

Now that the basics are learned, let’s get into SDN properly.

What resources are available to the Java Developer to deep-dive Spring Data Neo4j and required technologies and concepts, skipping what he already knows?

MATCH (sdn:Tech {name:"Spring Data Neo4j"})-[:REQUIRES*0..]->(technologyOrConcept)
      <-[teaches:TEACHES]-(resource),
      (javaDev:Person {name:"Java Developer"})
WHERE NOT (javaDev)-[:UNDERSTANDS]->(technologyOrConcept) OR teaches.level <> 'BASIC'
RETURN technologyOrConcept.name AS `Technology OR concept`,
       collect(DISTINCT resource.name) AS Resource
Loading table...

While learning, is there anybody that can be asked for help, how about the Spring Expert?

How many years of experience does the Spring Expert have with each technology?

MATCH (expert:Person {name:"Spring Expert"}), (expert)-[understands:UNDERSTANDS]->(tech:Tech)
RETURN tech.name AS Technology, (2013 - understands.since) AS `Years of experience`
Loading table...

Seems like the Spring Expert should know what he’s talking about.

Note that Dependency Injection is something the Spring Expert understands too, but it’s a Concept, not a Technology and this query was restricted to nodes with a Technology label.

Who can be asked for help on a specific technology?

MATCH (tech:Tech)<-[:UNDERSTANDS]-(person:Person)
RETURN tech.name AS Technology, collect(DISTINCT person.name) AS Person
Loading table...

The above query is more general and not asked from the standpoint of the Java Developer, so he’s listed too. This query hints at what can be done when extending the graph to include more developers and experts.

Finally, a query for the Java Developer who wants to understand what he’s doing properly.

What resources are available to the Java Developer to master existing skills?

MATCH (javaDev:Person {name:"Java Developer"})-[:UNDERSTANDS]->(technology:Tech)
      <-[:TEACHES]-(resource {level:"ADVANCED"})
RETURN technology.name as Technology, resource.name AS Resource
Loading table...

Further possibilities

With a bigger graph - when graphing the knowledge of several team members of a project, as previously hinted at - new possibilities arise: it could become possible to run queries to find 'enabler nodes', which are a prerequisite for multiple technologies and would therefore be well suited to broaden one’s understanding and knowledge. The graph would then basically be (the backend) for a learning recommendation engine. Albeit a simple one at this point.

Console to play around with the graph

Running queries, preparing the console!

Loading graph...

The sources (asciidoc, graphml) of this Gist are available here.