Niedawno opisywałem grafowy silnik bazy danych OQGRAPH. Dziś zajmiemy się lepszą, ciekawszą i, o dziwo, łatwiejszą bazą danych. Baza Neo4j opisuje grafy. Nie ma w niej tabel ani schematów znanych z SQL. Jest za to prostsza i łatwiej w niej opisać rzeczywisty świat.
Na początku musimy na chwilę zapomnieć o SQL. Zapomnijmy o takich pojęciach jak tabela w bazie. Nie będzie operacji JOIN ani tworzenia schematu bazy.
Każda baza Neo4j to swoisty jeden duży worek zawierający tylko dwa rodzaje danych: węzły i relacje.
Węzły czyli wszystkie rzeczowniki
Wezeł w Neo4j to pojedyncza struktura danych. Jeden punkt w przestrzeni. Węzeł może opisywać osobę, przedmiot, zwierzę, cechę, miasto… cokolwiek co przeważnie określamy rzeczownikami.
Węzły mają tylko trzy ważne cechy:
- Identyfikator – łatwo się domyślic po co
- Etykietę, która mówi nam czym jest dany węzeł
- Zestaw właściwości w postaci klucz-wartość.
Jeśli chcemy opisać osobę to stworzymy węzeł, który będzie miał etykietę „osoba” oraz właściwości, np. „imię: Adam”, „wzrost: 180”, „miasto: wrocław” itp.
Lista właściwości jest płynna. Możemy bez ograniczeń dodawać nowe, usuwać lub zmieniać istniejące. Nie ma schematu danych. Wpisujemy co tylko zechcemy.
Podobnie etykiety nie mają żadnych ograniczeń. Możemy z miejsca wymyślić nową etykietę tworząc po prostu węzeł zawierający ją. Chcemy dodać do bazy np. auto? Tworzymy węzeł z etykietą „samochód” i właściwościami takimi jak marka, model, typ silnika czy rok produkcji.
Gdy już mamy w naszej bazie węzły, czas je połączyć.
Relacje między węzłami
Relacja to po prostu powiązanie między dwoma węzłami. Relacja z węzła A do węzła B. Relacje mają dwie najważniejsze cechy:
- Typ relacji. Podobnie jak etykieta węzła, możemy nazwać go dowolnie.
- Zestaw właściwości, zupełnie jak w węzłach
Możemy teraz stworzyć relację. Nazwijmy ją np. „zna” albo „ma”. Będziemy teraz mogli powiązać dwa węzły, np:
Adam --zna--> Klaudia Ala --ma--> Kot
W pierwsym przypadku osoba zna inną osobę, w drugiej osoba ma kota (nieco błędnie bo koty myślą, że to one posiadają ludzi).
To wszystko, tylko tyle i aż tyle. Tak wygląda struktura bazy w Neo4J
Cypher Query Language czyli jak z tego korzystać?
Gdy już zainstalujemy Neo4j czas na trochę praktyki. Po uruchomieniu otwieramy przeglądarkę i wpisujemy adres http://localhost:7474/ gdzie otrzymujemy konsolę.
Zapytania podajemy podobnie jak w SQL ale w języku CQL. Dla programisty obeznanego z SQL nauka jest prosta. Trzeba pamiętać o trzech typach danych:
- (Nawiasy okrągłe) oznaczają węzły
- [Nawiasy kwadratowe] określają relacje
- {Nawiasy klamrowe} mówią nam o właściwościach.
Pamiętając o tym język jest prosty. Tworzenie węzła wygląda tak:
$ CREATE (:Osoba {imie:"Adam"}) Added 1 label, created 1 node, set 1 property, returned 0 rows in 153 ms
Właśnie utworzyliśmy węzeł o etykiecie „Osoba” i jednej właściwości.
Dwukropek przed etykietą jest ważny. CQL korzysta z możliwości przypisywania elementów zapytań do zmiennych. Możemy więc napisać tak:
$ CREATE (wezel:Osoba {imie:"Klaudia"}) RETURN wezel.imie Added 1 label, created 1 node, set 1 property, returned 1 row in 155 ms
Stworzyliśmy kolejny węzeł i od razu zwróciliśmy wartość jego właściwości. Tworzenie i zwracanie, tego nie było w SQL.
Skoro mamy już dwie osoby, spróbujmy stworzyć relację:
$ MATCH (kto:Osoba {imie:"Adam"}), (kogo:Osoba {imie:"Klaudia"}) CREATE kto -[:Zna]->kogo Created 1 relationship, returned 0 rows in 157 ms
Komenda MATCH powoduje znalezienie i dopasowanie węzłów do kryteriów wyszukiwania. Po naszemu powiedzieliśmy bazie „znajdź pierwszą osobę o imieniu Adam, drugą o imieniu Klaudia i połącz je relacją o typie Zna”.
Kluczowy jest tu operator relacji czyli strzałka z nawiasami kwadratowymi: -[]->
Wyszukiwanie relacji jest równie łatwe. Aby dowiedzieć się jaka relacja łączy Adama i Klaudię, wystarczy wpisać:
$ MATCH (a:Osoba)-[r]->(b:Osoba) WHERE a.imie = "Adam" AND b.imie = "Klaudia" RETURN type(r) Returned 1 row in 184 ms
Jak widać mamy tu klauzulę WHERE, której używamy bardzo podobnie jak w SQL. W podobny sposób możemy szukać wszystkich osób, które zna Adam itp.
CQL umożliwia nam także szukanie ścieżek między osobami. Gdybyśmy mieli więcej węzłów moglibyśmy np wyszukać wszystkie pary osób, które lubią koty. Najpierw dodajmy dane:
$ CREATE (co:Zwierze {gatunek:"Kot"}) Added 1 label, created 1 node, set 1 property, returned 0 rows in 178 ms $ MATCH (kto:Osoba),(co:Zwierze) CREATE (kto)-[:Lubi]->(co) Created 2 relationships, returned 0 rows in 180 ms
Jednym zapytaniem utworzyliśmy kota a kolejnym wyszukaliśmy wszystkie osoby, od razu dodaliśmy im relację. Teraz możemy szukać:
$ MATCH (a:Osoba)-[:Lubi]->(co:Zwierze)<-[:Lubi]-(b:Osoba) WHERE co.gatunek = "Kot" RETURN a,b Returned 2 rows in 199 ms
Widzimy, że operator relacji (strzałka) działa w obie strony. Właśnie stworzyliśmy nasz pierwszy serwis randkowy dopasowujący preferencje osób.
To tylko próbka możliwości Neo4j. Jak widać możemy dopasowywać do siebie ludzi na podstawie cech. Baza umożliwia nam znajdowanie ścieżek, operowanie na właściwościach, i płynną modyfikację danych.
Do czego to się przyda?
Możemy w niej zbudować np. bazę produktów sklepu i prostymi zapytaniami rekomendować klientom powiązane produkty (np. „Klienci, którzy to kupili oglądali też…”). Możemy tworzyć listy dostępu użytkowników z usługami. Gdy już zaczniemy myśleć grafami, możliwości są ogromne.
Co dalej?
Na pewno warto zacząć od strony Neo4j gdzie możemy pobrać darmową wersję i samemu bawić się zapytaniami. Warto przeczytać dokumentację języka CQL. W sieci jest dużo tutaoriali i przykładów działania tej bazy. Wśród baz grafowych, Neo4j jest obecnie najpopularniejsza i najszybciej się rozwijająca. Niebawem stanie się must-know w programowaniu.
Czy te bazy mają przyszłość? W rankingu db-engines wszystko wyglądało dobrze do listopada 2015, Neo4j piął się w górę. Od listopada jednak notuje lekki spadek. Ranking nie jest w pełni miarodajny, ale być może do załamanie rynku dla ww. bazy (może tylko tymczasowe). Szkoda, bo mi się technologia bardzo podoba, nabyłem nawet książkę i umiem nieco Cypher. Ciężko natomiast znaleźć w kraju grupę osób zainteresowanych tą technologią.
Ciężko powiedzieć. Mi bardzo się podoba idea grafowej bazy. Nie widziałem jednak praktycznego zastosowania. Na dodatek aby w pełni ją wykorzystać trzeba mocno przestawić w głowie sposób myślenia o bazach danych. Na pewno jeszcze przez lata ludzie będą używać SQL oraz baz typu Redis czy MongoDB.
Może warto utworzyć grupę zainteresowanych grafowymi bazami?
Fakt, idea jest bardzo fajna. Co do zastosowań to sądze, że jest ich sporo. Coraz więcej aplikacji korzysta z różnego rodzaju „profilowania” użytkowników a grafowe bazy wydają się wydajniejsze i łatwiejsze pod kątem przeszukiwania i dostosowywania w zależności od preferencji. Ciekaw jestem tylko ile kosztuje licencja enterprise na neo4j, bo nigdzie nie mogę się doszukać.
Może dlatego, że w zakładce „pricing” cena za enterprise to wynosi „prosimy o kontakt” :)