JavaScript &
les graph databases


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

ParisJS, 24 septembre 2014
Introduction
Objectif de la présentation :
- comprendre ce qu'est une graph database
- 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: 29
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
Tinkerpop
I. Modélisation

Example : Twitter
II. Requêtes
Gremlin
- Objectif : un langage unique pour interagir avec un graph (= sorte de SQL des bases graph).
- Pas un langage en soi : 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.


Gremlin CRUD
// 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
g.V('type', 'person').delete()// Update
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
.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 (un ou n vertex)
- naviguer vers d'autres vertex adjacents par l'intermédiaire d'éventuels edges
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-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
https://github.com/gulthor/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 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 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 qu'ils maitrisent déjà.
Et après?
- Créer un object-to-graph mapper (OGM/ORM) de référence en JavaScript : il faut aux bases graph ce que Mongoose est à MongoDB.
- Améliorer le support nashorn (Java 8)
- performance?
- steps surchargées
- Développer un moteur Gremlin en pur JavaScript?
- Développer une graph db en JavaScript?
Conclusion
- modèle générique (comme une base relationnelle)
- 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 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 modélisation des données
- ... de la façon de requêter
- technologie récente - relativement peu d'experts
Inconvénients
Questions ?
jbmusso@gmail.com
Twitter : @jbmusso
GitHub : @gulthor
(Thanks!)
20140926-javascript-and-graph-databases
By jbmusso
20140926-javascript-and-graph-databases
- 355