Tomek Poniatowicz
1/29/2019
Welcome to our Code Academy series in which we will try to present you useful tool, libraries and methods. This week we will focus on a Dgraph, a very promisng graph database. Dgraph is an open-source distributed graph database aimed at providing high production-level scale, efficient enough to be serving real-time user queries. Dgraph uses GraphQL as its default query language and responds in JSON. There has been a lot of talk in the media about Dgraph about a year ago when the company announced that it has raised $3 million in funding.
Dgraph is a distributed, highly available graph database. Unlike GraphQL, there is no concept of complex types or groups of properties. Dgraph defines the schema for properties within the graph, so you can store any GraphQL schema in Dgraph.
Dgraph cluster consists of three different nodes, each serving a different purpose:
If you want to give it a try the easiest way to do it is to use Docker (you will need also Docker Compose).
docker pull dgraph/dgraph
Once you have Docker Compose installed to start up Dgraph put below code in your docker-compose yaml file.
version: "3.2"
services:
zero:
image: "dgraph/dgraph:latest"
volumes:
- type: volume
source: dgraph
target: /dgraph
volume:
nocopy: true
ports:
- 5080:5080
- 6080:6080
restart: on-failure
command: dgraph zero --my=zero:5080
server:
image: "dgraph/dgraph:latest"
volumes:
- type: volume
source: dgraph
target: /dgraph
volume:
nocopy: true
ports:
- 8080:8080
- 9080:9080
restart: on-failure
command: dgraph alpha --my=server:7080 --lru_mb=2048 --zero=zero:5080
ratel:
image: "dgraph/dgraph:latest"
volumes:
- type: volume
source: dgraph
target: /dgraph
volume:
nocopy: true
ports:
- 8000:8000
command: dgraph-ratel
volumes:
dgraph:
Let's take A Song of Ice and Fire (aka. Game of Thrones) books series as our data set:
curl localhost:8080/mutate -H "X-Dgraph-CommitNow: true" -XPOST -d $'
{
set {
_:ned <name> "Eddard Stark" .
_:robert <name> "Robbert Baratheon" .
_:cersei <name> "Cersei Lannister" .
_:joffrey <name> "Joffrey Baratheon".
_:got1 <name> "A Song of Ice and Fire: A Game of Thrones" .
_:got1 <release_date> "1996-08-01" .
_:got1 <characters> _:ned .
_:got1 <characters> _:robert .
_:got1 <characters> _:cersei .
_:got1 <characters> _:joffrey .
_:got2 <name> "A Song of Ice and Fire:A Clash of Kings" .
_:got2 <release_date> "1998-11-16" .
_:got2 <characters> _:cersei .
_:got2 <characters> _:joffrey .
_:got3 <name> "A Song of Ice and Fire: A Storm of Swords" .
_:got3 <release_date> "2000-08-08" .
_:got3 <characters> _:cersei .
_:got3 <characters> _:joffrey .
}
}
' | python -m json.tool | less
You can alter your schema by adding indexes on some of data. This will allow queries to very convenient features as term matching, filtering and sorting:
curl localhost:8080/alter -XPOST -d $'
name: string @index(term) .
release_date: date @index(year) .
' | python -m json.tool | less
Having that done you can either query for all the books:
curl localhost:8080/query -XPOST -d $'
{
me(func: has(characters)) {
name
}
}
' | python -m json.tool | less
or query for just those published after year 2000:
curl localhost:8080/query -XPOST -d $'
{
me(func:allofterms(name, " A Song of Ice and Fire")) @filter(ge(release_date, "2000")) {
name
release_date
characters {
name
}
}
}
' | python -m json.tool | less
which will result in:
{
"data":{
"me":[
{
"name":"A Song of Ice and Fire: A Storm of Swords",
"release_date":"2000-08-08",
"characters":[
{
"name":"Cersei Lannister"
},
{
"name":"Joffrey Baratheon"
},
]
},
]
}
}
And that's it! Thanks to Mr. Dgraph Ratel we have a filtered data we have queried for.
Source: https://dgraph.io/