J@ArangoDB

{ "subject" : "ArangoDB", "tags": [ "multi-model", "nosql", "database" ] }

AQL Improvements in 2.5

Contained in 2.5 are some small but useful AQL language improvements plus several AQL optimizer improvements.

We are working on further AQL improvements for 2.5, but work is still ongoing. This post summarizes the improvements that are already completed and will be shipped with the initial ArangoDB 2.5 release.

Using Ccache When Working With Different Branches

Git makes working with many different branches in the same local repository easy and efficient.

In a C/C++ project, the code must be re-compiled after switching into another branch. If the branches only differ minimally, running make will only re-compile the parts that are actually different, and after that re-link them. That won’t take too long, though especially link times can be annoying.

However, if there are differences in central header files that are included from every file, then make has no option but to re-compile everything. This can take significant amounts of time (and coffee).

I just realized that there is a solution to speed up re-compilation in this situation: ccache!

Using ArangoDB as a Logstash Output

Inspired by a question on StackOverflow, I did some investigation about how to make Logstash send log events to ArangoDB.

There is no dedicated Logstash output plugin for ArangoDB on the Logstash plugins page, so I had already accepted to write one on my own.

Browsing the plugins page for inspiration, I found an HTTP output plugin for Logstash. It seems to be general enough that it can send the log event in JSON format to any HTTP-speaking backend.

ArangoDB’s API is JSON over HTTP, so it sounded like a perfect match. I briefly tried it out and it seemed to work fine.

Using Dynamic Attribute Names in AQL

On our mailing list, there is quite often the question whether attribute names in objects returned from AQL queries can be made dynamic.

Here’s a (non-working) example query for this:

example query that does not work
1
2
FOR doc IN collection
  RETURN { doc.type : doc.value }

The intention in the above query obviously is to use the dynamic value from doc.type as an attribute name in the result object and not to have an attribute named "doc.type". This feature is probably in the top 20 of the most-often wished features.

Using Custom Visitors in AQL Graph Traversals

Note: this post is about the ArangoDB 2.x series

This post is about some recent extensions for the AQL graph traversal functionality in ArangoDB.

These extensions allow invoking user-defined JavaScript code for filtering and results generation in AQL queries that contain traversals.

This should make AQL graph traversals much more powerful than before. Additionally, AQL graph traversals get more configurable, allowing to write traversal functions with control-flow logic and complex filtering. As a side-effect, this change facilitates writing specialized traversal functions with much higher efficiency than the general-purpose, cover-all-cases default ones.

The extensions are currently available in the devel branch of ArangoDB on in the 2.4 branch (with 2.4.2 being the first release to include them).

Explaining AQL Queries the Fancier Way

I have been looking at many AQL queries during the last few weeks.

Looking back, I can say that the JSON query execution plans provided by the explain() method have provided me with a lot of useful information about how the AQL optimizer had transformed a given query. This has helped testing and improving the query optimizer a great deal.

However, the JSON output produced by explain() is so detailed that even for the simplest cases queries it will span multiple screens. This is far too much for quicking assesing what a query will be doing and how it will be executed.

I therefore quickly put together a function that provides a much more compact explain output. Its input parameter is a query string, which it will send to the ArangoDB server to have it explained.

But it doesn’t print a voluminous JSON object. This one is for developers with a full schedule.

Returning Results From AQL INSERT/REMOVE/REPLACE Operations

ArangoDB provides many options for finding and modifying data. Though there are several more specialized operation, data-modification AQL queries are the most general solution in ArangoDB. They allow to find documents using arbitrary filter criteria, and to modify or remove the documents once found.

Such find-and-modify operations can be executed with multiple queries (one for the find step, one for the modification step), or with a single query. Putting both steps into a single query will often save roundtrips between the application and the database and thus may be preferred over executing the steps separately. Putting both the find and the modify step into the same query also prevents other operations from interfering in between and tampering with the underlying data.

Now what if the application not only requires the data to be updated, but also needs to keep track of which documents were found and modified by a find-and-modify query? This is often required when an application needs to keep database data in sync with data in some other datastore (e.g. the filesystem or a remote service).

The pattern I would dub find-modify-return would be useful for this.

Using ES6 Features in ArangoDB

ArangoDB 2.4 will be shipped with an updated version of V8.

The V8 version included in 2.4 will be 3.29.59. This version will replace the almost two year old 3.16.14. A lot of things happened in V8 since then, and a lot of ES6 features have been added to it.

ES6 is not finalized yet, and support for it is a work in progress on all platforms.

ES6 provides many cool features that can make JavaScript developer’s life easier. In this blog post, I’ll summarize a few ES6 features that are available in ArangoDB, either for scripting purposes in the ArangoShell, or in your server-side Foxx actions inside the database.

I don’t want to put you off until Doomsday. ArangoDB 2.4 should be released next week. Time to play with some ES6 features!

99 Bottles of Beer

99 bottles of beer in AQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
FOR quant IN 99..0 
  LET toPrint = (
    quant > 1 ? 
      CONCAT(TO_STRING(quant), " bottles of beer on the wall, ", TO_STRING(quant), " bottles of beer.") : 
      (quant == 1 ? 
        "1 bottle of beer on the wall, 1 bottle of beer." :
        "No more bottles of beer on the wall, no more bottles of beer."
      )
  )
 
  LET suffix = (
    quant > 2 ? 
      CONCAT(TO_STRING(quant - 1), " bottles of beer on the wall.") :
      (quant == 2 ? 
        "1 bottle of beer on the wall." :
        "no more bottles of beer on the wall."
      )
  )
 
  LET result = (
    quant > 0 ? 
      CONCAT(toPrint, "\nTake one down, pass it around, ", suffix) : 
      CONCAT(toPrint, "\nGo to the store and buy some more, 99 bottles of beer on the wall.")
  )

  RETURN result