0
votes

I have a graph representing levels in a game. Some examples of types of nodes I have are "Level", "Room", "Chair". The types are represented by VertexCollections where one collection is called "Level" etc. They are connected by edges from separate EdgeCollections, for example "Level" -roomEdge-> "Room" -chairEdge-> "Chair". Rooms can also contain rooms etc. so the depth is unknown.

I want to start at an arbitrary "Level"-vertex and traverse the whole subtree and find all chairs that belong to the level.

I'm trying to see if ArangoDB would work better than OrientDB for me, in OrientDB I use the query:

SELECT FROM (TRAVERSE out() FROM startNode) WHERE @class = 'Chair'

I have tried the AQL query:

FOR v IN 1..6 OUTBOUND @startVertex GRAPH 'testDb' FILTER IS_SAME_COLLECTION('Chair', v) == true RETURN v;

It does however seem to be executing much slower compared to the OrientDB query(~1 second vs ~0.1 second).

The code im using for the query is the following:

String statement = "FOR v IN 1..6 OUTBOUND @startVertex GRAPH 'testDb' FILTER IS_SAME_COLLECTION('Chair', v) == true RETURN v";
timer.start();
ArangoCursor<BaseDocument> cursor = db.query(statement, new MapBuilder().put("startVertex", "Level/"+startNode.getKey()).get(), BaseDocument.class);
timer.saveTime();

Both solutions are running on the same hardware without any optimization done, both databases are used "out of the box". Both cases use the same data (~1 million vertices) and return the same result.

So my question is if I'm doing things correctly in my AQL query or is there a better way to do it? Have I misunderstood the concept of VertexCollections and how they're used?

1

1 Answers

0
votes

Is there a reason you have multiple collections for each entity type, e.g. one collection for Rooms, one for Levels, one for Chairs?

One option is to have a single collection that contains your entities, and you identify the type of entity it is with a type: "Chair" or type: "Level" key on the document.

You then have a single relationship collection, that holds edges both _to and _from the entity collection.

You can then start at a given node (for example a Level) and find all entities of type Chair that it is connected to with a query like:

FOR v, e, p IN 1..6 OUTBOUND Level_ID Relationship_Collection
FILTER p.vertices[-1].Type == 'Chair'
RETURN v

You could return v (final vertex) or e (final edge) or p (all paths).

I'm not sure you need to use a graph object, rather use a relationships collection that adds relationships to your entity collection.

Graphs are good if you need them, but not necessary for traversal queries. Read the documentation at ArangoDB to see if you need them, usually I don't use them as using a graph can slow performance down a little bit.

Remember to look at indexes, and use the 'Explain' feature in the UI to see how your indexes are being used. Maybe add a hash index to the 'Type' key.