Blog Kokosa

.NET i okolice, wydajność, architektura i wszystko inne

NAVIGATION - SEARCH

Memory Visualizer - Cypher, co to jest?!

Obiekty w pamięci tworzą całkiem rozbudowany graf. Mają pomiędzy sobą referencje, są też poukładane w segmenty w ramach pamięci procesu, które to możemy potraktować również jako kolejny węzeł w grafie. W tym sensie segment może być rodzicem wielu obiektów, które zawiera itd. W każdym bądź razie, tak jak już było obiecane, pora zastanowić się nad językiem zapytań do owych grafów. Choć padały inne propozycje (m.in. użycie SPARQL), ja jednak pozostaję pod nieustającym wrażeniem prostoty i przejrzystości języka Cypher, używanego w grafowej bazie danych Neo4j. Świetny kurs znajdziecie na stronie owej bazy danych. W ramach ultra szybkiego wprowadzenia, jest to język ASCII podobny, opisujący co chcemy w grafie znaleźć. Węzły oznaczamy za pomocą (), relacje za pomocą -->. Dodatkowo zarówno węzły jak i relacje mogą mieć atrybuty. W efekcie, wszystko jest naprawdę intuicyjne, co stara się tłumaczyć poniższa grafika ze strony neo4j:

Np. w grafie gdzie mamy węzły aktorów (węzły typu Person), filmów i relacji pomiędzy nimi (m.in. relacji typu ACTED_IN), zapytanie o tytuły filmów, w których grał Tom Hanks może wyglądać:

MATCH (tom:Person)-[:ACTED_IN]->(movie)
WHERE tom.name="Tom Hanks"
RETURN movie.title;

Czy jest coś bardziej intuicyjnego? Chyba sobie nie wyobrażam. A jak znaleźć wszystkich aktorów, którzy zagrali w filmie razem z Gene Hackmanem? O tak:

MATCH (gene:Person)-[:ACTED_IN]->(m),
(other)-[:ACTED_IN]->(m)
WHERE gene.name="Gene Hackman"
RETURN DISTINCT other;

To jest świetne i samo się tłumaczy. I tego użyję jako mój autorski Memory Query Language - bo MQL to świetny skrót!

MQL, podobnie jak Cypher, umożliwia agregacje, np. możemy wyświetlić w ilu filmach zagrała każda osoba:

MATCH (a:Person)-[:ACTED_IN]->(m)
RETURN a.name, count(m)

Ale ja funkcję typu count albo sum mogę wykorzystywać jako atrybut wynikowej relacji albo węzła (np. uzależniając wielkość węzła od sumy rozmiaru obiektów, które na niego wskazują itd.).

Na początku obawiałem się, czy Cypher jako taki wystarczy do zapytań, ktore chcę wykonywać. Ale po przejrzeniu się dokładniej, chyba tak! W następnym wpisie pokażę dokładnie, jak wyobrażam sobie zapytania do przykładowych rysunków z pierwszego wpisu.

Na koniec przykład zapytania pokazującego wszystkie osoby, które znają osoby, które znają Keanu Reevsa. To tak do myślenia, w jakich zapytaniach MQL może się to przydać :)

 MATCH p = (keanu:Person)-[:KNOWS*2]->(fof)
 WHERE keanu.name = "Keanu Reeves"
 RETURN nodes(p), rels(p)
blog comments powered by Disqus