Skip to content

Instantly share code, notes, and snippets.

@sim51
Last active December 17, 2015 05:58
Show Gist options
  • Save sim51/5561322 to your computer and use it in GitHub Desktop.
Save sim51/5561322 to your computer and use it in GitHub Desktop.
La promesse des bases de données orientées graphe c'est d'être veleda ready ! Plus besoin de convertir notre modèle. #hype
@charset "UTF-8";
body{
background:url("https://raw.github.com/sim51/prez-neo4j/gh-pages/img/background.png") no-repeat bottom #000000;
background-size: 100%;
color: #FFFFFF;
font-size:0.9em;
}
.reveal ol, .reveal ul {
list-style: none outside none;
}
.reveal section .footnote {
font-size: 0.7em;
font-style: italic;
margin-top: 100px;
display:block;
}
.reveal section h1{
font-size:1.8em;
margin-bottom: 10px;
}
.reveal section *{
text-align:center;
}
.reveal section ul,.reveal section ul li, .reveal section ul li * {
text-align:left;
}
.reveal section ul.center,
.reveal section ul.center li,
.reveal section ul.center li * {
text-align:center;
}
.reveal section ul li{
margin-top:20px;
margin-bottom:20px;
}
.reveal section blockquote{
font-size:0.7em;
width:100%;
}
.reveal section blockquote.small{
font-size:0.5em;
text-align:left;
}
.reveal section p.comment{
text-align:left;
font-size:0.7em;
color:green;
}
.reveal section div.code *{
text-align:left;
}
div#footer{
position:fixed;
bottom: 10px;
left: 50px;
}
.reveal section img{
border : none;
background: none;
}
.reveal section strong {
color: #13DAEC;
}
footer {
position:fixed;
bottom:2px;
font-size:0.5em !important;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Neo4j - JUG Nantes</title>
<meta name="description" content="Prendre un veleda pour modéliser ses données, c'est ce que nous faisons régulièrement. Cependant à chaque fois nous devons traduire notre modèle en MCD pour l'insérer dans un SGBD.
La promesse des bases de données orientées graphe c'est d'être veleda ready ! Plus besoin de convertir notre modèle.Lors de cette présentation nous vous parlerons de Neo4j, une base données NoSQL orientée graph écrite en java, ainsi que des concepts qui gravitent autour.">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="http://lab.hakim.se/reveal-js/css/reveal.min.css">
<link rel="stylesheet" href="http://lab.hakim.se/reveal-js/css/theme/default.css" id="theme">
<link rel="Stylesheet" href="https://rawgithub.com/sim51/5561322/raw/Neo4j%20-%20JUG%20Nantes.css" />
<!-- ###HYPE_CSS### -->
<!-- For syntax highlighting
<link rel="stylesheet" href="lib/css/zenburn.css">
-->
<!-- If the query includes 'print-pdf', use the PDF print sheet -->
<script>
document.write( '<link rel="stylesheet" href="http://lab.hakim.se/reveal-js/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
</script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.6.2/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<!-- Presentation-->
<section>
<h1>Welcome to the matrix <br/> with Neo4j</h1>
<img src="http://sim51.github.io/prez-neo4j/img/neo4j.png">
<p>
<small>
<a href="http://www.bsimard.com">Benoît Simard</a>
/
<a href="http://twitter.com/logisima">@logisima</a>
</small>
</p>
</section>
<section>
<q>
<strong>Neo4j</strong> is a <strong>NO-SQL Graph</strong> database, it's written in <strong>java</strong> and it's <strong>open-source* !</strong><span class="tiny"></span>
</q>
<span class="footnote">* (A)GPLv3 but also Neo Technology Commercial License (NTCL)</span>
</section>
<section>
<img src="http://sim51.github.io/prez-neo4j/img/linkedin.jpg" width="500px"/>
</section>
<section>
<h1>NoSQL</h1>
<img src="http://sim51.github.io/prez-neo4j/img/nosql-graph.png" />
</section>
<section>
<h1>Linked data</h1>
<img src="http://sim51.github.io/prez-websemantique/img/web_datas.jpg" />
</section>
<section>
<img src="http://sim51.github.io/prez-neo4j/img/graphdb-compare-rdbms.svg" width="500px"/>
</section>
<section>
<img src="http://cdn.sheknows.com/articles/2012/01/national-spaghetti-day.jpg" />
</section>
<!--
<section>
<h1>Some limitations</h1>
<ul>
<li>2ˆ35 (~ 34 billion) nodes</li>
<li>2ˆ35 (~ 34 billion) relationships</li>
<li>2ˆ36 (~ 68 billion) properties</li>
<li>2ˆ15 (~ 32 000) relationship types</li>
</ul>
<span class="footnote">Plan for 2013 : higher limits for real big data</span>
</section>
-->
<!-- Part I : what is a graph database ? -->
<section>
<section>
<h1>What is a graph <br/>database ?</h1>
<img src="http://sim51.github.io/prez-neo4j/img/graphDB-logo.png" />
</section>
<section>
<img src="http://sim51.github.io/prez-neo4j/img/graphDB.png" />
</section>
<section>
<img src="http://sim51.github.io/prez-neo4j/img/node.png" />
<span class="footnote">v2.0 : Nodes could have labels</span>
</section>
<section>
<img src="http://sim51.github.io/prez-neo4j/img/edge.png" />
</section>
<section>
<img src="http://sim51.github.io/prez-neo4j/img/property.png" />
</section>
<section>
<h1>Find out if a person get a specific role</h1>
<img src="http://sim51.github.io/prez-neo4j/img/example-role.png" />
</section>
<section>
<h1>Recommandation system</h1>
<p>Find out the possible new friends based on them liking similar things</p>
<img src="http://sim51.github.io/prez-neo4j/img/recommandations.svg" />
</section>
</section>
<!-- Part II : How to query a graph -->
<section>
<section>
<h1>How to query my graph</h1>
<img src="http://sim51.github.io/prez-neo4j/img/graphDB-logo.png" />
</section>
<section>
<h1>Indexes</h1>
<img src="http://sim51.github.io/prez-neo4j/img/indexes.png" /><br/>
<span>Create indexes manualy or use auto-indexing</span>
</section>
<section>
<h1>Traversal</h1>
<img src="http://sim51.github.io/prez-neo4j/img/traversal.svg" />
</section>
<section>
<h1>Depth or breadth first</h1>
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Depth-First-Search.gif/250px-Depth-First-Search.gif" />
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Breadth-First-Search-Algorithm.gif/250px-Breadth-First-Search-Algorithm.gif" />
</section>
<section>
<h1>Some DSL</h1>
<img src="http://sim51.github.io/prez-neo4j/img/cypher.jpg" />
<img src="http://sim51.github.io/prez-neo4j/img/gremlins.jpg" />
</section>
<section>
<h1><img src="http://sim51.github.io/prez-neo4j/img/gremlin.png" /></h1>
<ul>
<li>Written in Groovy</li>
<li>Graph (G) = Vertex(node) , Edge(relationship)</li>
<li>Based on a generic Graph API: <a href="https://github.com/tinkerpop/blueprints/wiki">Blueprints</a></li>
</ul>
</section>
<section>
<h1><img src="http://sim51.github.io/prez-neo4j/img/gremlin.png" /></h1>
<ul>
<li>Blueprints impl: <i>TinkerGraph, Neo4j, OrientDB, DEX, InfiniteGraph, Rexster, and Sail RDF</i></li>
<li>Everything in Gremlin is an iterator</li>
<li>Each operation is a pipe</li>
</ul>
</section>
<section>
<h1><img src="http://sim51.github.io/prez-neo4j/img/gremlin.png" /></h1>
<br />
<div class="code">
<p class="comment">// Display "name" of all node<p/>
<blockquote>g.V.name</blockquote>
</div>
<br/>
<div class="code">
<p class="comment">// Complex query :<p/>
<blockquote>g.v(23).out('knows').filter{it.age > 30}.out('like').name</blockquote>
</div>
</section>
<section>
<h1>Cypher</h1>
<ul class="center">
<li>Human query language</li>
<li>Inspired by SQL</li>
<li>Only avaible for Neo4j</li>
</ul>
</section>
<section>
<h1>Pattern</h1>
<ul>
<li>
<strong>START</strong>: Starting points in the graph, obtained by element IDs or via index lookups
</li>
<li>
<strong>MATCH</strong>: The graph pattern to match, bound to the starting points in <code class="literal">START</code>
</li>
<li>
<strong>WHERE</strong>: Filtering criteria
</li>
<li>
<strong>RETURN</strong>: What to return
</li>
</ul>
<span class="footnote"><a href="http://docs.neo4j.org/refcard/1.9/">Reference card</a></span>
</section>
<section>
<h1>Sample query</h1>
<br/>
<div class="code">
<p class="comment">// All node related to node 3<p/>
<blockquote>start n=(3) match (n)--(x) return x</blockquote>
</div>
<br/>
<div class="code">
<p class="comment">// All node that are BLOCKed by node 3<p/>
<blockquote>start n=(3) match (n)-[r, :BLOCKS]-> (x) return x</blockquote>
</div>
<br/>
<div class="code">
<p class="comment">// All BLOCKS relationships outgoing from node 3<p/>
<blockquote>start n=(3) match (n)-[r, :BLOCKS]-> () return r</blockquote>
</div>
<br/>
<div class="code">
<p class="comment">// Where regex<p/>
<blockquote>start n=(2,1) match n.name =~ /Tob.*/ return n</blockquote>
</div>
</section>
<section>
<h1>Complexe query</h1>
<img src="http://sim51.github.io/prez-neo4j/img/cypher-collab-graph.svg" style="display:block;float:left"/>
<div style="display:block;float:left; margin-left:50px;margin-top:30px">
<blockquote class="small">
<strong>START</strong><br/>
&nbsp;&nbsp;joe=node:node_auto_index(name = "Joe")<br/>
<strong>MATCH</strong><br />
&nbsp;&nbsp;joe-[:knows]->friend-[:knows]->friend_of_friend,<br/>
&nbsp;&nbsp;joe-[r?:knows]->friend_of_friend<br/>
<strong>WHERE</strong> r IS NULL<br/>
<strong>RETURN</strong> friend_of_friend.name, COUNT(*)<br/>
<strong>ORDER BY COUNT</strong> (*) DESC, friend_of_friend.name<br/>
</blockquote>
</div>
</section>
<section>
<h1>Client</h1>
<ul>
<li>REST API</li>
<li>Java : natif client (embedded), spring-data, play!</li>
<li>Ruby, Python, Php, Javascript, .Net ...</li>
</ul>
</section>
<section>
<h1>REST API - Node</h1>
<ul>
<li><blockquote>http://localhost:7474/db/data/node/{id}</blockquote></li>
<li><blockquote>http://localhost:7474/db/data/node/{id}/properties/{key} </blockquote></li>
<li><blockquote>http://localhost:7474/db/data/node/{id}/relationships/{in|out} </blockquote></li>
</ul>
<br/>
<ul>
<li>
<blockquote>
curl --header "Content-Type: application/json" --data '{"foo":"bar"}' http://localhost:7474/db/data/node
</blockquote>
</li>
<li>
<blockquote>
curl http://localhost:7474/db/data/node/14
</blockquote>
</li>
</ul>
</section>
<section>
<h1>REST API - Relationship</h1>
<ul>
<li><blockquote>http://localhost:7474/db/data/relationship/{id}</blockquote></li>
<li><blockquote>http://localhost:7474/db/data/relationship/{id}/properties/{key} </blockquote></li>
<li><blockquote>http://localhost:7474/db/data/node/{id}/relationships</blockquote></li>
</ul>
<br/>
<ul>
<li>
<blockquote>
curl --header "Content-Type: application/json" --data '{"to" : "http://localhost:7474/db/data/node/6", "type" : "LINK", "data" : {"foo" : "bar"}}' http://localhost:7474/db/data/node/0/relationships
</blockquote>
</li>
<li>
<blockquote>
curl http://localhost:7474/db/data/relationship/25
</blockquote>
</li>
</ul>
</section>
<section>
<h1>Some tools</h1>
<ul>
<li>Neoclipse</li>
<li>Gephi</li>
<li>Web admin</li>
<li>Linkurious</li>
</ul>
</section>
</section>
<!-- Part III : les transaction -->
<section>
<section>
<h1>Transaction</h1>
<img src="http://sim51.github.io/prez-neo4j/img/graphDB-logo.png" />
</section>
<section>
<img src="http://flexitrain.files.wordpress.com/2013/04/acid.png" />
<p>All write operations must be performed in a transaction. </p>
</section>
<section>
<h1>Cycle</h1>
<ol>
<li>Begin a transaction</li>
<li>Operate on the graph performing write operations</li>
<li>Mark the transaction as successful or not</li>
<li>Finish the transaction</li>
</ol>
</section>
<section>
<h1>REST-API - transaction *</h1>
<div class="request">
<ul>
<li><strong>POST </strong>http://localhost:7474/db/data/transaction</li>
<li>
<div class="code">
{<br/>
"statements" : [ {<br/>
&nbsp;&nbsp;"statement" : "CREATE (n {props}) RETURN n",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;"parameters" : {<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"props" : {<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"name" : "My Node"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;&nbsp;&nbsp;} ]<br/>
}
</div>
</li>
</ul>
</div>
<span class="footnote">* Only in version 2.0, for above there is batch mode</span>
</section>
<section>
<h1>REST-API - transaction *</h1>
<div class="response">
<ul>
<li>Code <strong>201</strong></li>
<li>
<div class="code">
{<br/>
&nbsp;&nbsp;"commit" : "http://localhost:7474/db/data/transaction/4/commit",<br/>
...<br/>
}
</div>
</li>
<li/>
<li>
<p>Adding statements</p>
&nbsp;&nbsp;
<strong>POST</strong>
http://localhost:7474/db/data/transaction/4
</li>
<li>
<p>Commit</p>
&nbsp;&nbsp;
<strong>POST</strong>
http://localhost:7474/db/data/transaction/4/commit
</li>
<li>
<p>Rollback</p>
&nbsp;&nbsp;
<strong>DELETE</strong>
http://localhost:7474/db/data/transaction/4
</li>
</ul>
</div>
<span class="footnote">* Only in version 2.0, for above there is batch mode</span>
</section>
<section>
<h1>Lock</h1>
<img src="http://sim51.github.io/prez-neo4j/img/lock.gif" />
</section>
<section>
<h1>Lock</h1>
<div class="code">
<p class="comment">// Working on a property of a node (or a relationship)<p/>
<blockquote>lock the node (or the relationship)</blockquote>
</div>
<div class="code">
<p class="comment">// Create, remove a node<p/>
<blockquote>lock the node</blockquote>
</div>
<div class="code">
<p class="comment">// Create, remove a relationship<p/>
<blockquote>lock relationship and its nodes</blockquote>
</div>
</section>
<section>
<h1>In memory write operation</h1>
<img src="http://sim51.github.io/prez-neo4j/img/homer-brain.jpg" width="500px"/>
</section>
</section>
<!-- Part III : Extension -->
<section>
<section>
<h1>How to extend Neo4j ?</h1>
<img src="http://sim51.github.io/prez-neo4j/img/graphDB-logo.png" />
</section>
<section>
<h1>Extension</h1>
<p>Don't care of endpoint,JSON format, It's a part of the Neo4j process !</p>
<img src="http://sim51.github.io/prez-neo4j/img/extension.png" />
</section>
<section>
<h1>Plugin</h1>
<p>Based on JAX-RS, You can do what ever you want, JSON result depend on you !</p>
<img src="http://sim51.github.io/prez-neo4j/img/plugin.png" />
</section>
<section>
<h1>List of extension</h1>
<ul class="center">
<li>Gremlin & Cypher</li>
<li>RDF / Sparql</li>
<li>Spatial</li>
</ul>
</section>
<section>
<h1>Spatial & OSM</h1>
<img src="http://sim51.github.io/prez-neo4j/img/osm.png"/>
</section>
</section>
<!-- Part IV : Backup -->
<section>
<section>
<h1>Backup</h1>
<img src="http://sim51.github.io/prez-neo4j/img/graphDB-logo.png" />
</section>
<section>
<ul>
<li>Save the index !</li>
<li>Hot backup process (EE)</li>
</ul>
</section>
</section>
<!-- Part V : Cluster -->
<section>
<section>
<h1>Cluster</h1>
<img src="http://sim51.github.io/prez-neo4j/img/graphDB-logo.png" />
</section>
<section>
<img src="http://sim51.github.io/prez-neo4j/img/cluster.png" />
</section>
<section>
<h1>Master</h1>
<ul>
<li>Unique</li>
<li>Read / write</li>
<li>Elected by the cluster (Via Apache ZooKeeper)</li>
</ul>
</section>
<section>
<h1>Slaves</h1>
<ul>
<li>Many</li>
<li>Read-only</li>
<li>redirect write query to master</li>
</ul>
</section>
</section>
<section>
<h1>Some examples</h1>
<ul>
<li><a href="http://zenithub.logisima.com">Zentihub</a>: A recommandation system for github</li>
<li><a href="http://console.neo4j.org/">Neo4j console</a>: A cypher console to test neo4j </li>
<li><a href="https://github.com/drazzib/neo4j-examples">Neo4j examples</a>: Java sample code with Spring Data and Gremlin</li>
</ul>
</section>
<section>
<section>
<h1>Competitors</h1>
</section>
<section>
<h1><a href="http://www.orientdb.org/">OrientDB</a></h1>
<ul>
<li>Hybrid Document <i>and</i> Graph database</li>
<li>Multi-master architecture</li>
<li>Support for SQL queries</li>
<li>Liberal Apache 2 license</li>
</ul>
</section>
<section>
<h1><a href="http://thinkaurelius.github.io/titan/">Titan</a></h1>
<ul>
<li>Consistency choice via <a href="https://github.com/thinkaurelius/titan/wiki/Storage-Backend-Overview">pluggable storage architecture</a>:
<ul>
<li>Cassandra: eventually consistent</li>
<li>HBase: vertex consistent</li>
<li>BerkeleyDB: ACID<!-- single machine : HA but no sharding --></li>
</ul>
</li>
<li>Young product...</li>
<li>Liberal Apache 2 license</li>
</ul>
</section>
</section>
<section>
<h1>Thanks to</h1>
<ul>
<li>Neo-technology</li>
<li>Peter Neubauer (I re-use some illustration)</li>
<li>You !</li>
</ul>
<span class="footnote">You can see this presentation <a href="http://hype.logisima.com/prez/view/5561322/Neo4j%20-%20JUG%20Nantes">here</a></span>
</section>
</div>
<footer>
Follow this presentation in live:
<a href="http://bit.ly/16vs1EA">http://bit.ly/16vs1EA</a>
</footer>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/headjs/0.99/head.min.js"></script>
<script src="http://lab.hakim.se/reveal-js/js/reveal.min.js"></script>
<script type="text/javascript">
// Full list of configuration options available here:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: false, // don't set to true if you want to edit your prez with hype, because it reload the iframe
center: true,
theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
// Optional libraries used to extend on reveal.js
dependencies: [
{ src: 'https://raw.github.com/hakimel/reveal.js/v2.3/lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'https://raw.github.com/hakimel/reveal.js/v2.3/plugin/markdown/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'https://raw.github.com/hakimel/reveal.js/v2.3/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }
]
});
</script>
<!-- DO NOT REMOVE THE LINE ABOVE -->
<!-- ###HYPE_INJECTION_CODE### -->
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment