TSM - NEO4j Graph Database modelarea datelor interconectate

Iulian Moșneagu - Senior Software Engineer

Neo4j este o baza de date open-source fondată pe teoria grafurilor, fiind o soluție optimizată pentru a modela și interoga volume mari de date strâns relaționate, reprezentabile prin structuri de tip graf. Dinamismul,creșterea volumului datelor, precum și evolutia continuă a procesării informațiilora impus ieșirea din spațiul bazelor de date relaționale tradiționale și orientarea spre soluții NOSQL.

Neo4j face parte din fenomenul NOSQL încadrându-se încategoria bazelor de date de tip graf. O caracteristică unică a acestora este gradul ridicat de adaptibilitate la modelele reale de date.

NOSQL Stores

Atât în cazul bazelor de date relaționale cât și în cazul unor soluțiiNOSQL (non-graph) procesulde modelare / design trece prin două faze :

De cele mai multe ori modelul logic este foarte diferit de modelul fizic. În cadrul unei organizații software în prima fază poate participa orice echipă nu neapărat tehnică(management / sales ) pentru o mai bună definire a cerințelor sau conceptelor.În cea de a doua fază însă are loc abstractizarea modelului logic în funcție de opțiunea de stocare. Astfel gradul de înțelegere al modelului logic scade odată cu creșterea complexității datelor.

Marele avantaj al bazelor de date de tip graf și implicit utilizarea Neo4j este că modelul logic este același cu modelul fizic. Având acest mod de reprezentare uniformă sau astfel spus o reprezentare "human readable" ce oferă un mare grad de flexibilitate , adaptibilitate și expresivitate în modelarea datelor reale.

Acest tip de bază de date permite o abordare iterativă putând fi utilizată cu succes în strategia de development de tip Agile.

Reprezentarea datelor în Neo4J

În Neo4j datele sunt reprezentate prin noduri și relații. Atât nodurile cât și relațiile pot fi avea proprietăți.Relațiile au un rol foarte important în cadrul bazei de date de tip graf pentru că traversarea grafului și implicit manipularea datelor se realizează prin intermediul lor.

O relație implică întotdeauna două noduri, are o direcțieși un tip identificat unic printr-un nume.

În exemplul de mai sus relația "KNOWS" conectează nodurile "Autor 1" cu "Autor 2 " precizând de asemenea proprietatea adițională "since".

Relativ la un nod relațiile se pot clasifica în două tipuri :

Atât proprietățile unui nod cât și cele aleunei relații pot fi indexate pentru îmbunătățirea performanței de traversare a grafului ( similar cu indexarea coloanelor în bazele de date tradiționale ).

Forțând o comparație cu bazele de date tradiționale, vă puteți imagina un nod ca o înregistrare dintr-un tabel, iar o relație ca o înregistrare dintr-un tabel de legătură sau o pereche de coloane din același tabel în cazul unei reprezentări tip denormalizat.

Limbajul de interogare Cypher

Neo4j are propriul limbaj de interogare a datelor organizate în structuri de graf.Este folosit conceptul de "Traversal" prin intermediul căruia se navighează în graf, se indentifică drumurile și implicit se selecteză nodurile pentru rezultatul unei interogări.

Limbajul Cypher este un limbaj de interogare declarativ fiind foarte intuitiv și "human readable", putând fi înțeles cu ușurință chiar și de o persoană non-tehnică.

Unele cuvinte cheie sunt inspirate din SQL cum ar fi: where, order by , limit, skip (echivalentul offset)

Limbajul este alcătuind din următoarele clauze :

Pentru exemplificare vă propun următorul graf care reprezintă autorii care publică în TSM relaționați după cum urmează :

Graful de mai sus se poate crea cu următoarea instrucțiune Cypher :

CREATE autor1 = { name : "Autor1, worksAt : 
 "Company1" }, 
articol1 = { title : "Articol1" }, articol2= { title
 : "Articol2" }, 	
 
(autor1)-[:Wrote]->(articol1), 
 (autor1)-[:Wrote]->(articol2),
 
revista = { name : "TSM", domain : "IT" , poweredBy:"Gemini Solutions"},
(articol1)-[:Published_in {date:"2013} ]->(revista),
 
autor2 = { name : "Autor2, worksAt : "Company2" }, 
articol3 = { title : "Articol3" }, (autor2)-[:Wrote]->(articol3)},
autor3 = { name : "Autor3, worksAt : "Company3" }, 
articol4 = { title : " Articol4" }, (autor3)-
[:Wrote]->(articol4)} 
(autor2)-[:Knows]->(autor3),
subject1 = { subject : " Spring Framework" }, 
 subject2 = { subject : " NOSQL },
 
subject3 = { subject : " Agile" },subject4 = { subject : " Android"},
(autor1)-[:Interested_in]->(subject1), (autor1)-[:Interested_in]->(subject3), 
(autor2)-[:Interested_in]->(subject2),(autor3)-[:Interested_in]->(subject4);

Cum observați și mai sus crearea nodurilor și a relațiilor este foarte intuitivă și flexibilă.

Exemple de interogări pe graful de mai sus:

 

1.start n=node(*) match n-[:WROTE]->(a) return n, count(a) 
(rezultatul va afisa fiecare autor cu numarul de articolo publicate)
 
2.start magazine=node(*) match magazine<-[:Published_in]-(article)<-[:Wrote]-(author)-[:Interested_in]->(subject) where magazine.name?=""TSM" and subject.subject?="Java" return author.name, article; 	
(rezultatul va afisa toate articolele cu subiectul Java impreuna cu numele autorului)
3.start n=node(*)match n<-[:Published_in]-(article) return count(article)
( rezulatul afiseaza numarul de articolo publicate în TSM)

În cazul în careavem milioane de autori și avem cerința de a adăuga o nouă relație ( ex. RATING între un autor și un articol), trebuie doar adăugată relația și funcționalitatea de a conecta autori cu articole se poate realiza. În cadrul unei baze de date relaționale, operațile de modificare de schema sunt de obicei costisitoare și nu neapărat simple.

Astfel că se poate spune ca modelul evoluează în mod natural odată cu datele reale și cerințele impuse de business.

SpringData și Neo4j

Neo4j expune un API Java foarte variat care permite crearea și manipularea grafurilor.

O alta opțiune este utilizarea platformei REST. Fondatorii Spring Framework au creat un nou modul adresat bazelor de date NOSQL.

Numele lui este String Data și are la bază aceeași abstactizare a interacțiunii cu bazele de date princonceptul "Templates" ( ex. JDBCTemplate) .

Ca analogie, la fel cum interacțiunea cu SQL se realizează prin hibernate, interacțiunea cu Cypher se realizează prin Spring Data Neo4j support.