Migrating GRAPH_* Measurements from 2.8 or earlier to 3.0

Problem

With the release of 3.0 all GRAPH functions have been dropped from AQL in favor of a more native integration of graph features into the query language. I have used the old graph functions and want to upgrade to 3.0.

Graph functions covered in this recipe:

  • GRAPH_ABSOLUTE_BETWEENNESS
  • GRAPH_ABSOLUTE_CLOSENESS
  • GRAPH_ABSOLUTE_ECCENTRICITY
  • GRAPH_BETWEENNESS
  • GRAPH_CLOSENESS
  • GRAPH_DIAMETER
  • GRAPH_ECCENTRICITY
  • GRAPH_RADIUS

Solution 1: User Defined Funtions

Registering user-defined functions

This step has to be executed once on ArangoDB for every database we are using.

We connect to arangodb with arangosh to issue the following commands two:

var graphs = require("@arangodb/general-graph");
graphs._registerCompatibilityFunctions();

These have registered all old GRAPH_* functions as user-defined functions again, with the prefix arangodb::.

Modify the application code

Next we have to go through our application code and replace all calls to GRAPH_* by arangodb::GRAPH_*. Now run a testrun of our application and check if it worked. If it worked we are ready to go.

Important Information

The user defined functions will call translated subqueries (as described in Solution 2). The optimizer does not know anything about these subqueries beforehand and cannot optimize the whole plan. Also there might be read/write constellations that are forbidden in user-defined functions, therefore a "really" translated query may work while the user-defined function work around may be rejected.

The general graph module still offers the measurement functions. As these are typically computation expensive and create long running queries it is recommended to not use them in combination with other AQL features. Therefore the best idea is to offer these measurements directly via an API using FOXX.

First we create a new Foxx service. Then we include the general-graph module in the service. For every measurement we need we simply offer a GET route to read this measurement.

As an example we do the GRAPH_RADIUS:

/// ADD FOXX CODE ABOVE

const joi = require('joi');
const createRouter = require('@arangodb/foxx/router');
const dd = require('dedent');
const router = createRouter();

const graphs = require("@arangodb/general-graph");

router.get('/radius/:graph', function(req, res) {
  let graph;

  // Load the graph
  try {
    graph = graphs._graph(req.graph);
  } catch (e) {
    res.throw('not found');
  }
  res.json(graphs._radius()); // Return the radius
})
.pathParam('graph', joi.string().required(), 'The name of the graph')
.error('not found', 'Graph with this name does not exist.')
.summary('Compute the Radius')
.description(dd`
  This function computes the radius of the given graph
  and returns it.
`);

Author: Michael Hackstein

Tags: #howto #aql #migration