I am trying to integrate Cayley's, a graph database's query language Gizmo, into Rye. To do this, I need to get to know it well enough. Not just the exact query language, but I need a better understanding of how to solve problems with graph databases.
Since outside of the official documentation and tutorial, I couldn't find many resources about Gizmo, I decided to write this down.
I am using the 30kmoviedata graph, that you can find on Cayley's Github repository. AFAIK the graph includes at least a network of movies, directors and actors. I will try to compare the Gizmo to SQL where applicable.
I am just learning, take it all with a grain of salt and let me know if I made any mistakes.
Very basics
Let's start with the basics and get a title of a film based on ID. In SQL this would be something like:
select name from film where id = "/en/alien_1979";
and in Cayley's Gizmo:
g.V().Is("</en/alien_1979>").Out("<name>").All()
The query language is based on Gremlin, and looks like JavaScript. "g" and "V()" stand for "graph" and "Vertex()".
In general we find some nodes and then follow the path to more nodes. Name is not a property of the film node per-se, but another node with a "<name>" edge.
Vertex is another name for node, edges for links between the nodes.
Predicates
Functions Out and In follow the links from current nodes. You can use them without an argument to follow any type of link, or with, to specify it.
g.V().Is("</en/alien_1979>").Out().All() { "result": [ { "id": "</en/ridley_scott>" }, { "id": "_:2597" }, ... more of these ... { "id": "Alien" }, { "id": "</film/film>" } ] }
This wasn't very helpfull. We got all the nodes, that a film links to. To see what kinds of links are possible we use functions OutPredicates and InPredicates:
g.V().Is("</en/alien_1979>").OutPredicates().All() { "result": [ { "id": "</film/film/directed_by>" }, { "id": "</film/film/starring>" }, { "id": "<name>" }, { "id": "<type>" } ] }
So our film node links to it's directors, actors, it's name and type.
InPredicates in the case above doesn't return anything, so nothing links to it.
Finding director(s)
We can see above, that a film node points to it's directors. Let's get the names of them, for this movie:
graph.V().Is("</en/alien_1979>").Out("</film/film/directed_by>").Out("<name>").All() { "result": [ { "id": "Ridley Scott" } ] }
At first thought, we would do this in SQL with a single join:
select p.name
from films f join people p on f.directed_by = p.id
where f.id = "/en/alien_1979";
But there is a problem, as we will see later, a film can have more than one directors, so we need an additional many-to-many table, which makes the code a little more messy:
select p.name from films f join film2director f2d on f.id = f2d.id_film join people p on p.id = f2d.id_director where f.id = "/en/alien_1979";
We get a little deeper in the next blog-post.
Komentarji
Objavite komentar