home shape

Building AQL Query Strings: Tips and Best Practices | ArangoDB Blog

I recently wrote two recipes about generating AQL query strings. They are contained in the ArangoDB cookbook by now:

After that, Github user tracker1 suggested in Github issue 1457 to take the ES6 template string variant even further, using a generator function for string building, and also using promises and ES7 async/await.

We can’t use ES7 async/await in ArangoDB at the moment due to lacking support in V8, but the suggested template string generator function seemed to be an obvious improvement that deserved inclusion in ArangoDB.

Basically, the suggestion is to use regular JavaScript variables/expressions in the template string and have them substituted safely.

With regular AQL bind parameters, a query looks like this:

var bindVars = { name: "test" };
var query = `FOR doc IN collection 
         FILTER doc.name == @name 
         RETURN doc._key`;
db._query(query, bindVars);

This is immune to parameter injection, because the query string and the bind parameter value are passed in separately. But it’s not very ES6-y.

Now, after partly implementing

tracker1‘s suggestion, JavaScript values and expressions can be used much more naturally when building AQL query strings:

var name = "test"; 
var query = aqlQuery`FOR doc IN collection 
                 FILTER doc.name == ${name} 
                 RETURN doc._key`;
db._query(query);

${name} is regular ES template string syntax and would normally be substituted with the value of JavaScript variable name. Such simple substitution would be unsafe, because it would make the query vulnerable to parameter injection. So we’re also using a template string generator function named aqlQuery. This function comes bundled with ArangoDB 2.7.

Under the hood, aqlQuery will create regular AQL bind parameters for each occurrence of a template string parameter. It will keep the query string and the actual bind parameter values separate, so it is safe to use.

The function will return an object with that can directly be passed on to the db._query() function. Here’s what aqlQuery will generate for the above example (note: some whitespace was removed from the output):

{ 
  "query" : "FOR doc IN collection FILTER doc.name == @value0 RETURN doc._key", 
  "bindVars" : { 
  "value0" : "test" 
 } 
}

The aqlQuery template string generator function is available in 2.7, which is currently in development. The changes are contained in the devel branch only at the moment, but will become available in following 2.7 release. A pull request has been issued to have the cookbook recipes updated to include aqlQuery, too.

aqlQuery can be used in 2.7 from the ArangoShell, inside arangod (e.g. from inside Foxx actions) and from ArangoDB’s web interface.

All other variants for building AQL queries are still fully supported.

This article was published first on Jan’s Blog

Jan Steemann

Jan Steemann

After more than 30 years of playing around with 8 bit computers, assembler and scripting languages, Jan decided to move on to work in database engineering. Jan is now a senior C/C++ developer with the ArangoDB core team, being there from version 0.1. He is mostly working on performance optimization, storage engines and the querying functionality. He also wrote most of AQL (ArangoDB’s query language).

Leave a Comment





Get the latest tutorials, blog posts and news: