I'm brand new to ArangoDB. I'm familiar with Neo4J, but was drawn to ArangoDB's performance and multi-model design. The documentation seems very deep, but I'm having trouble getting started.
I would like to know a simple way to do some basic graph operations. All I've found so far tells me how to connect entire collections together, but I would like to simply be able to define a node, define another node, and define the edge between them.
Ideally via HTTP, how can I:
As an example, I would like to create a simple graph like the tree illustrated here: https://www.arangodb.com/2015/07/data-modeling-with-multi-model-databases/
I'd like basic instructions on how to create a subset of this graph. I would like to:
airline0
and airline1
in a collection called fleets
. plane0
, plane1
, plane2
in a collection called planes
. - Put an arbitrary attribute in each plane's document- let's say color.Jennifer
in a collection called pilots
. Next, I would like to connect up the graph. Based on the documentation, it looks like edges themselves are documents, and thus can have attributes. I'd like to create the following edges:
(airline0)-[owns]->(plane0)
(airline0)-[owns]->(plane1)
this edge has since: 2013
as an attribute(airline1)-[owns]->(plane2)
(airline1)-[previouslyOwned]->(plane1)
between: [1999,2013]
(plane0)-[inFleet]->(airline0)
(plane1)-[inFleet]->(airline0)
(plane1)-[wasInFleet]->(airline1)
between: [1999,2013]
(plane2)-[inFleet]->(airline1)
(jennifer)-[canfly]->(plane0)
(plane0)-[hasPilot]->(jennifer)
Please show me how I can create such a graph via HTTP. If not HTTP, I'd like to know how to do this via arangosh.
Let me start with the arangosh, because it is easier to read. I'll give the HTTP commands as an addendum.
ArangoDB Shell
You would need the three document collections "fleets", "planes", and "pilots" as you mentioned above and an at least one edge collection to hold the graph structure. If you want to traverse the graph structure jumping between "owns" and "inFleet" and "canfly", I suggest to use one collection "relations" and give the edges an attribute "type".
An alternative solution is to use three edge collections "owns" and "inFleet" and "canfly". In order to make a more fact-based recommendation, it would be good to know more about your use-case.
arangosh [_system]> db._create("fleets");
[ArangoCollection 139792431, "fleets" (type document, status loaded)]
arangosh [_system]> db._create("planes");
[ArangoCollection 140382255, "planes" (type document, status loaded)]
arangosh [_system]> db._create("pilots");
[ArangoCollection 140972079, "pilots" (type document, status loaded)]
arangosh [_system]> db._createEdgeCollection("relations");
[ArangoCollection 141103151, "relations" (type edge, status loaded)]
Next, create the documents in the collection "fleets". I will use the name of the airline as key. Depending on your use case, there might be a better key. For example, maybe there is a universal abbreviation (like LH for Lufthansa).
arangosh [_system]> db.fleets.save({ _key: "airline0", name: "Airline 0" });
arangosh [_system]> db.fleets.save({ _key: "airline1", name: "Airline 1" });
Repeat the same for planes and pilots:
arangosh [_system]> db.planes.save({ _key: "plane0", name: "Plane Zero", color: "red" })
arangosh [_system]> db.planes.save({ _key: "plane1", name: "Plane One", color: "red" })
arangosh [_system]> db.planes.save({ _key: "plane2", name: "Plane One", color: "green" })
arangosh [_system]> db.pilots.save({ _key: "jennifer", name: "Jenifer" });
You should select the keys according to your use-case. If there are no "natural" keys, then leave out the "_key" attribute. ArangoDB will generate a unique key for you.
Next, add the relations between the nodes creates above. The syntax in ArangoDB 2.8 is similar to creating a document above. In addition, you need to supply the "from" and "to" keys of the vertices, you want to connect.
arangosh [_system]> db.relations.save("fleets/airline0", "planes/plane0", { type: 'owns' });
arangosh [_system]> db.relations.save("fleets/airline0", "planes/plane1", { type: 'owns', since: 2013 });
arangosh [_system]> db.relations.save("fleets/airline1", "planes/plane2", { type: 'owns' });
arangosh [_system]> db.relations.save("fleets/airline1", "planes/plane1", { type: 'previouslyOwned', begin: 1999, end: 2013 });
arangosh [_system]> db.relations.save("pilots/jennifer", "planes/plane0", { type: 'canfly' });
If 'inFleet' / 'wasInFleet' / 'hasPilot' is the reverse of 'owns' / 'previouslyOwned' / 'canfly', than you do not need to create a separate edge for it, because edges are directional.
If there are differences between 'owns' and 'inFleet' you can create the relations similar to the above:
arangosh [_system]> db.relations.save("planes/plane0", "fleets/airline0", { type: 'inFleet' });
...
Now in order to follow the path "jennifer can fly planeX owned by airlineY" use:
arangosh> db._query("FOR v, e IN OUTBOUND 'pilots/jennifer' relations FILTER e.type == 'canfly' FOR w, f IN INBOUND v relations FILTER f.type == 'owns' RETURN { plane: v, airline: w }")
[
{
"plane" : {
"color" : "red",
"name" : "Plane Zero",
"_id" : "planes/plane0",
"_rev" : "153686063",
"_key" : "plane0"
},
"airline" : {
"name" : "Airline 0",
"_id" : "fleets/airline0",
"_rev" : "149884975",
"_key" : "airline0"
}
}
]
Or to reverse the path (without using 'inFleet' and 'hasPilot'):
arangosh> db._query("FOR v, e IN OUTBOUND 'fleets/airline0' relations FILTER e.type == 'owns' FOR w, f IN INBOUND v relations FILTER f.type == 'canfly' RETURN { plane: v, w: w }")
[
{
"plane" : {
"color" : "red",
"name" : "Plane Zero",
"_id" : "planes/plane0",
"_rev" : "153686063",
"_key" : "plane0"
},
"w" : {
"_id" : "pilots/jennifer",
"_rev" : "330240047",
"_key" : "jennifer"
}
}
]
HTTP
Let me give you example for the various types of commands executed above.
arangosh [_system]> db._create("fleets");
this translates to
curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection <<EOF
{
"name" : "fleets"
}
EOF
Next
arangosh [_system]> db._createEdgeCollection("relations");
translates to
curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection <<EOF
{
"name" : "relations", "type": 3
}
EOF
Next
arangosh [_system]> db.fleets.save({ _key: "airline0", name: "Airline 0" });
translates to
curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products <<EOF
{ "_key": "airline0", "name": "Airline 0" }
EOF
Next
db.relations.save("pilots/jennifer", "planes/plane0", { type: 'canfly' });
translates to
curl -X POST --data-binary @- --dump - http://localhost:8529/_api/edge/?collection=relations&from=pilots/jennifer&to=planes/plane0 <<EOF
{
"type" : "canfly"
}
EOF
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With