specimen
specimen

Reputation: 1765

Keep first occurence of value when traversing up a tree in ArangoDB

I'm traversing a tree, and want to keep only the first occurence of each object (based on an attribute of the edge). It's kind of like the example with inheritance from the cookbook for modelling inheritance (https://github.com/arangodb/docs/blob/2c842774b457114c571abdaa8391a038715d1458/3.3/cookbook/document-inheritance.md).

In my program, I have a tree of tasks and sub tasks (infinite levels). From some of the tasks there are edges pointing to people. On the edges there are an attribute called "role". Given that I start on a task far down in the tree and traverse upwards, I'd like to keep only the first (nearest) occurence of each unique role (and the person having that role).

Could something like this be done in pure AQL, or is a visitor function the way to go?

Upvotes: 1

Views: 66

Answers (1)

mchacki
mchacki

Reputation: 3267

You can register a self defined visitor function to the server, this can than be used by AQL. In your case something like this could do the trick:

  • Copy/Paste the following into arangosh to register the function:

var functions = require("org/arangodb/aql/functions"); functions.register("myvisitor::role", function (config, result, vertex, path) { if (result.length === 0) { result.push({found: {}, result: {}}); } var role = path.edges[path.edges.length -1].role; if (role !== undefined && !result[0].found.hasOwnProperty(role)) { result[0].found[role] = true; /* Store in result[0].result whatever you like */ } });

  • Note in AQL the result of the traversal is always an array. So we only use the first entry in this array to store a document with the real information.

Now you can use this visitor from AQL:

FOR r IN TRAVERSAL(@@vertices, @@edges, @startId, "inbound", {visitor: "myvisitor::role"}) RETURN r[0].result

or in the GRAPH_TRAVERSAL:

FOR r IN GRAPH_TRAVERSAL(@graph, @startId, "inbound", {visitor: "myvisitor::role"}) RETURN r[0].result

Upvotes: 2

Related Questions