home shape

ArangoDB Query Builder: Simplifying Database Queries

The most powerful way to query your data in ArangoDB is by using ArangoDB’s own query language, AQL. In the past using AQL in your JavaScript code sadly would often require writing long, unwieldy strings. This made writing complex queries difficult and could often lead to subtle syntax errors or mistakes.

The ArangoDB Query Builder (AQB) is a JavaScript node packaged module that provides a fluid API for writing AQL queries in plain JavaScript. And if you’re using ArangoDB 2.3, the aqb module is already available to your Foxx applications. Let’s say we want to perform the following query in our Foxx application using the new query builder:

FOR u IN users
  FILTER u.authData.active == true
  RETURN u.userData.email

First we need to import the query builder module:

var qb = require('aqb');

The query builder provides chainable methods for the AQL keywords:

qb.for('u').in('users').return('u.userData.email')

Note that the keyword methods are lowercase to fit in more naturally in JavaScript. Also note that reference names and literals don’t need any special escaping. If you pass in a string, the query builder will assume it’s meant to be a reference name and throw an error if it is not well-formed:

qb.for('this is not a valid reference name') // throws an error

In order to define filters and other expressions, the query builder provides helper methods:

qb.eq('u.authData.active', true) // u.authData.active == true

Let’s say we want to build the query dynamically and use a variable instead of simply passing in true. The query builder provides additional methods to enforce data types, for example:

var active = true;
qb.eq('u.authData.active', qb.bool(active)) // u.authData.active == true

You can even construct reference names dynamically:

var prop = 'email';
qb.get('u.userData', qb.ref(prop)) // u.userData.email

In Foxx applications you generally want to use auto-prefixed collection names to avoid conflicts between multiple copies of the same application. Wherever the query builder expects a reference name for a collection, you can simply pass in a collection object directly:

qb.for('u').in(applicationContext.collection('users'))

In ArangoDB 2.3 and newer, you can also simply pass in query builder instances wherever an AQL query string would normally be expected:

db._query(qb.for('u').in('users').return('u')).toArray()

If you want to use the query builder with older versions of ArangoDB or outside of ArangoDB entirely, you can just call its toAQL method to convert it into a regular string:

db._query(qb.for('u').in('users').return('u').toAQL()).toArray()

Here’s the full translation of the AQL we started with:

qb.for('u').in('users')
.filter(qb.eq('u.authData.active', true))
.return('u.userData.email')

Now let’s use what we’ve learned to turn that query into something more flexible:

var qb = require('aqb');
var db = require('org/arangodb').db;

function getUserPropsByActive(prop, active) {
    return db._query(
      qb.for('u').in('users')
      .filter(qb.eq('u.authData.active', qb.bool(active)))
      .return(qb.get('u.userData', qb.ref(prop)))
    ).toArray();
}

var activeUserEmails = getUserPropsByActive('email', true);
print(activeUserEmails);

Note that you can also use the query builder to construct parameterized queries:

var userEmailsByActive = (
    qb.for('u').in('users')
    .filter(qb.eq('u.authData.active', '@active'))
    .return('u.userData.email')
);

var activeUserEmails = db._createStatement({
    query: userEmailsByActive,
    bindVars: {active: true}
}).execute().toArray();
print(activeUserEmails);

More information on the ArangoDB Query Builder can be found on GitHub and on NPM.

If you want to continue with other JavaScript related resources, you should start with ArangoDB NoSQL and JavaScript.

Alan Plum avatar 1418721602 92x92

Alan Plum

Alan is an experienced web developer who feels equally at home in the backend and frontend. At ArangoDB he works on everything regarding JavaScript, with a special focus on Foxx.

1 Comments

  1. you on May 27, 2020 at 6:36 am

    I don’t think it is helpful to me,
    In daily life, we need more queryBuilder APIs like mongoose or sequelize. Is there such a library?
    model(“XX”).find({ username:”luke” }).limit(0,10).populate(“something”)

Leave a Comment





Get the latest tutorials, blog posts and news: