JavaScript &
les graph databases


Jean-Baptiste Musso
- GitHub : @jbmusso
- Twitter : @jbmusso

NantesJS, 17 mars 2015

Introduction
Objectif de la présentation :
- comprendre ce qu'est une base de données graphe
- comprendre comment interagir avec une graph database depuis un environnement JavaScript (Node.js/Browser)
- Un graphe est un ensemble de noeuds (vertex/vertices) connectés entre eux par des liens (edge/edges)
- Chaque lien a une direction et un label
- Les noeuds et les liens (éléments du graphe) peuvent avoir des propriétés qui les décrivent
likes
name: "jbmusso"
age: 30
type: "person"
since: 2012
name: "JavaScript"
type: "language"
Un graphe

Intérêt : permet de développer son application sans (trop) se soucier de la base graphe utilisée.
Framework Open Source
- Une API qui définit un graphe : Blueprints
- Un serveur : Gremlin Server, interface entre la database et l'application
- Un langage de requête : Gremlin
Apache TinkerPop
I. Modélisation

Example : Twitter
II. Requêtes
Gremlin
- Un langage unique pour interagir avec un graphe
- objectif : être le SQL des bases graphe
- Pas stricto sensu un langage, mais un DSL avec une implémentation de référence en Groovy (qui expose donc toute l'API Java).
- Existe une variante expérimentale JavaScript (Java8/nashorn), et aussi Python, Scala, etc.


Gremlin CRUD (TP2)
// Ajouter Seb et Marie dans le graph
seb = g.addVertex(['type': 'user', 'name': 'Seb'])
marie = g.addVertex(['type': 'user', 'name': 'Marie'])
// Ajouter une relation de type follow de Seb vers Marie
g.addEdge(seb, marie, 'follows', ['since': 20140924])
// Delete toutes les vertex de type 'person'
g.V('type', 'person').delete()// Update sur tous les vertex de type 'user'
g.V('type', 'user').sideEffect({
it.setProperty('type') = 'person'
})// Récupérer tous les utilisateurs
g.V('type', 'user');
// Récupérer tous les utilisateurs qui s'appellent Bob
g.V('type', 'user').has('name', 'Marie');Gremlin traversals
g.v(1).as('myself') // Point de départ, stocké en tant que 'myself'
.out('follow') // Trouver les utilisateurs que je follow
.out('follow') // Pour chacun, trouver ceux qu\'ils suivent
.dedup() // Filtrer les doublons éventuels
.except('myself') // Filtrer le point de départPrincipe général :
- définir un point de départ : 1-n vertex, 1-n edge
- naviguer vers d'autres vertices adjacents par l'intermédiaire des edges incidents (entrants et/ou sortants)
Exemple : trouver tous les utilisateurs suivis (followed) par les utilisateurs que je suis (follow) moi-même.
Requêtes types
- Recommendation :
- les clients qui ont acheté cet objet ont aussi acheté... (ex: Amazon)
- vous pourriez devenir ami avec... (ex: Facebook).
- Recherche de chemin :
- X est connecté à Y par l'intermédiaire de... (ex: LinkedIn)
- le chemin "le plus court" / "rapide" ou "le moins cher" entre mon entrepôt et mon client est...
- détection de fraudes
- Classement : algorithme PageRank (ex: Google).
- Etc.
III. Gremlin JavaScript
gremlin-client (js)
Client JavaScript bas niveau pour Gremlin Server (ex Rexster)
- Etablit une connexion permanente à Gremlin Server (WebSocket)
- Envoie des strings de Gremlin plus ou moins grandes, avec éventuellement des paramètres (bindings)
- Exécute l'intégralité du script et renvoie un flux de résultats
- Futur client intégré dans Apache TinkerPop 3
https://github.com/jbmusso/gremlin-client
API
client.execute(script, params, function(err, results) {
if (!err) {
console.log(results); // Array
}
});Mode callback
Mode stream
var gremlin = require('gremlin-client');
var client = gremlin.createClient(8182, 'localhost');
var script = 'g.V("name", userName)';
var params = { userName: 'Bob' };var vertexStream = client.stream(script, params);
vertexStream.on('data', function(vertex) {
console.log(vertex)
});
Streams
- client.stream() renvoie un stream d'objets qui émet les résultats (vertices ou edges typiquement) 1 par 1 à mesure que Gremlin Server les renvoie
- chaque stream peut ensuite être .pipe() dans un autre stream Node.js (transform/write) : utile avec les librairies utilitaires telles que event-stream, Highlandjs.js, through2, etc.
var es = require('event-stream');
vertexStream
.pipe(es.map(function(vertex, callback) {
vertex.fromNode = true;
callback(null, vertex);
}))
.pipe(es.stringify());
Gremlin en JS avec nashorn
var gremlin = require('gremlin-client');
var client = gremlin.createClient({ language: 'nashorn' });
// Expérimental: création d'une fonction dont la seule utilité
// est de récupérer son body avec Function.toString();
var script = function() {
g.V("type", user).filter(function(it) {
return it.get().value('name') === nameFilter;
});
}
var s = client.stream(script, { type: 'user', nameFilter = 'Bob' });
Objectif : permettre aux développeurs JavaScript de commencer plus rapidement avec Gremlin en écrivant des requêtes dans un langage dont ils connaissent déjà la syntaxe.
- Implémentation d'une base graphe in-memory :
- https://github.com/jbmusso/tinkergraph-js
- Implémentation de Gremlin en JavaScript :
- https://github.com/jbmusso/gremlin-core-js
- Interagir avec les librairies JavaScript de manipulation de graphe via Gremlin (Sigma.js, D3.js, etc.):
- https://github.com/jbmusso/gremlin-sigma
Les autres librairies JavaScript
Conclusion
- modèle aussi générique que le modèle relationnel
- modèle très proche de la façon dont le cerveau humain appréhende l'information
- modèle idéal pour les données très connectées
- c'est-à-dire, lorsqu'il y a davantage de valeur *entre* les données que *dans* les données en elles-mêmes
Avantages
- apprendre à penser autrement, tant s'agissant :
- ... de la façon dont on modélise les données
- ... de la façon de requêter (avec Gremlin)
- technologie récente - relativement peu d'experts
Inconvénients
Questions ?
jbmusso@gmail.com
Twitter : @jbmusso
GitHub : @jbmusso
(Thanks!)
20150317-nantesjs-javascript-and-graph-databases
By jbmusso
20150317-nantesjs-javascript-and-graph-databases
- 173