Graph database (Java ile Neo4j Kullanımı)
Bundan önceki senelerde veritabanı deyince aklımıza relational veritabanlarından başka bir şey gelmezdi.
İhtiyaçlar yeni teknolojiler doğurdu, NoSQL popülerleşti.
Son zamanlarda graph database kavramını çok sık duymaya başladım ve araştırıp edindiğim bilgiler doğrultusunda sizlere anlatacağım.
Öncelikle Graph database, matematikte graph theory olarak geçen yapıyı birebir model alan veri tabanı. Nesneler tablolarda değilde graph’larda tutuluyor.
Bir kayıt node yada edge olabiliyor. Edge’ler nodelar arasında yönleri (birectional) nesneleri tutuyor.
Öğrenci sınıf ilişkisinde 2 node(öğrenci, sınıf), 2 edge (“X sınıfına gidiyor”, “Y benim öğrencim”) var.
Graph veritabanı nesneler arasındaki bağlantıların (relation) en az nesneler kadar önem taşıdığı modeller için tasarlanmış.
Facebook, Linkedin gibi milyon kaydın birbiriyle ilişkisini en hızlı sorgulamaya çalışan sistemleri aday sistemler olarak düşünebiliriz.
Java da örneğimize başlayalım …
İlk olarak
http://www.neo4j.org/install adresinden kullandığınız işletim sistemine göre neo4j yi download ediniz ve graph database arayüzümüzü https://github.com/neo4j/neoclipse/downloads bu adresten indirelim…
Bu arada dökümantasyonu burada http://docs.neo4j.org/
Oluşturduğumuz java projemize indirdiğimiz neo4j kütüphanepimizi ekliyelim …
Şimdi kodumuzu yazmaya başlayalım ilk önce databasemizi oluşturalım .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class DenemeNeoStudent { public final static String NEO_INDEX_PATH = "C:\\Users\\MehmetKilic\\Desktop\\neo\\neo"; static Node root; static GraphDatabaseService graphDb; public static void createDatabase() { graphDb = new EmbeddedGraphDatabase(DenemeNeoMeMo.NEO_INDEX_PATH); // Burada databasemizi export edecek bir dizin soruyor bize bizde yukarda dizinimizi vermiştik zaten registerShutdownHook(graphDb); // veritabanımızın kapamasını sağlar root = graphDb.getReferenceNode(); // Oluşturduğumuz veritabanımızdan bir tane Node için referans alıyoruz bunu aşağıda user eklerken kullanacagız.. } } // Databasemizi sağlıklı bir şikilde kapatmaya yarıyan method private static void registerShutdownHook(final GraphDatabaseService graphDb) { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { graphDb.shutdown(); } }); } |
Bu şekilde run edersek eğer kodumuzu gösterdiimiz dizine databasemizi create eder ama içi boş olur .
Şimdi gelelim içini doldurmaya zaten graph database kullanıcının yoğun olduğu sistemlerde çok hızlı sorgular için kullanılır ve nesneler arası bağlantıları daha iyi analiz etmemiz için tasarlanmıştır şimdi küçük bir örnek yapalım 10 tane öğrencimiz olsun (adı , soyadı , okulu , fakültesi ve grup no) ve her öğrencininde 5 er tane dersi olsun (her dersinde o dönemki puanları olsun)
İlk önce ozaman öğrenci nesnemizi oluşturalım burada nesne derken tablo olarak algılayın siz ..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
public static void createStudent() throws SQLException { // Neo4j Transaction ile çalısır yani işlem sırasında bir hata oluştumu hiçbirsey yapmaz işlem başa geri alınır. Transaction tx = null; try { tx = graphDb.beginTx(); // Databasemizi kullanamız için Transaction başlayıtoruz . int b = 0; StudentList sl = new StudentList(); while (b < 10) { Node node = graphDb.createNode(); // Burada her öğrenci nesnemizi bir node olarak düşünelim .. node.setProperty("userid", sl.getStudentList()[b][0]); // Her öğrenciniz bilgilerini set ediyoruz arkadaşlar ben bir diziden çektim bilgileri node.setProperty("firstName", sl.getStudentList()[b][1]); node.setProperty("lastName", sl.getStudentList()[b][2]); node.setProperty("faculty", sl.getStudentList()[b][3]); node.setProperty("group", sl.getStudentList()[b][4]); root.createRelationshipTo(node, Gorevi.STUDENT); // Node ‘i ve ilişki tipini burada yukarda olusturdugumuz Node yolluyoruz System.out.println("\tNeo Profile Olusturuldu : " + node.getProperty("firstName")); b++; } tx.success(); // Transaction tamamlanması .. } catch (Exception e) { tx.failure(); // hata zamanı System.out.println("\tNeo Transaction Olusturulamadi" + e); } finally { if (tx != null) { tx.finish(); // Transaction bitirilmesi System.out.println("\tNeo Transaction Bitti"); } } } // İlişki tipini enum şekilde oluşturuyoruz public static enum Gorevi implements RelationshipType { STUDENT, LESSONS } |
Şuanda kodumuzu çalıştırsak kaç tane öğrenci eklediysek bunu oluşturucaktır .. Burada direkt relational databasemizi (oracle , mysql vs ) gerekli connectionları oluşturup neo4j’ye aktarabilirdik ama daha sade ve anlaşılır olması için böyle bir yolu seçtim …
Şimdi gelelim oluşturduğumuz her öğrenciye derselerini ekleyelim …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
private static void createLessons() throws SQLException { Transaction tx = null; try { tx = graphDb.beginTx(); Traverser traverser = root.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL_BUT_START_NODE, Gorevi.STUDENT, Direction.OUTGOING); int count = 0; for (Node node : traverser.getAllNodes()) { Node dersler = graphDb.createNode(); dersler.setProperty("Yapay Zeka", "88"); dersler.setProperty("Gelişmiş Bilgisayar Şebekeleri", "73"); dersler.setProperty("Bilişim Etiği ", "92"); dersler.setProperty("Gerçek Zaman Sistemleri ", "93"); dersler.setProperty("Bilgi Güvenliği", "95"); node.createRelationshipTo(dersler, Gorevi.LESSONS); tx.success(); System.out.println(count+" . "+"öğrenciye dersleri eklendi.."); count++; } } catch (Exception ex) { tx.failure(); System.out.println("\tDersler Oluşturulmadı"); System.out.println("==================================="); ex.printStackTrace(); System.out.println("==================================="); } finally { tx.finish(); } } |
// Burada dikkat edilmesi gereken olay Traverser dir .. for a girerken traverser.getAllNodes()) şeklinde bir kod yazmışız bu su demek oluyor bizim databasemizindeki bütün nesneleri çağırır . ve her döngüse bir nesneye aşağıdaki belirttiğimiz dersleri ekler .. ve bunu for un üstündeki şu kod parçasıyla anlar hangi ilişki türünden nesneye hangi dersleri ekleyeceği.Altta açıklıyalım onu …
Traverser traverser = root.traverse(Order.DEPTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
Gorevi.STUDENT, Direction.OUTGOING);
Buradaki Gorevi.STUDENT hani biz yukarda databasemizi çağırdığımızda bize tüm nesneleri (öğrencileri) getirmişti yaa oradaki ilişki tipi student olan nesnelere bu dersleri eklemesini söyledik.. Direction.OUTGOING bu dışa doğru yayılma yani ağaç mantıgını düşünün …
Kodumuzu bu şekilde çalıştırdığımızda sorunsuz çalışması lazım ve yukarda verdiğimiz dizinede yüklediğimiz neoeclipse de çalıştıracağımız türden bize klasör olusturcak.. O tarafını resimlerle anlatayım arkadaşlar ..
Neoeclipseyi açtıktan sonra sol taraftaki connection bloguna gelerek sağ tıklayıp new conneciton diyoruz ve sonra şekilde görüldüğü gibi bir isim yazıyoruz ve dizini browse diyerek seçiyoruz ve tamam diyoruz.
Ve sonrasındada olusturdugumuz connecitonu çalıştırdıgımız zaman graph databasemizi kullanama başlayabiliriz Her öğrenciye tıkladıgımızda onun derslerinin listesi ve notları gelicek .
Öğrenci dersleri ve notları 😉
neo4j-ogm kütüphanesini kullanarak yapılan örnek : http://www.turkishh.com/programlama/neo4j-ogm-graph-mapping-object-ile-java-ornek/
Umarım yararlı olmuştur 😉
İyi Çalışmalar
ELLERINIZE SAGLIK HOCAM! 🙂