AQL update syntax for nested documents

992 views
Skip to first unread message

Hello Max

unread,
Oct 23, 2014, 5:21:56 PM10/23/14
to aran...@googlegroups.com
Hi

New to ArangoDb, using the PHP Driver and I'm struggling with the AQL update syntax for nested documents.
Basically an "addToSet" as with MongoDb.

Pseudo document in profiles collection

{
    '_key'    : '81855392035',
    'doc'     : 'profile',
    'name'    : 'John',
    'surname' : 'Jones',
}


I want to add the following e mail contact to a yet-to-be-created array in the above document.

$email = json_encode(array('name' => 'Peter Smith',
                                         'at'      => 'pe...@nowhere.com',
                                        'type'   => 'business'));

// The path to array: detail.cnx.e (using a dot syntax)
$update = "for p in profiles
                     filter p.doc == @doc && p._key == @key
                     update p with {detail:{'cnx':{'e': $email}}} in
                     profiles";

$bindVars = array('doc'=>'profile', 'key'=> '81855392035');

Executing the statement with the above creates the email in the specified array.

The old $email is overwritten when I repeat the statement with a new $email.  I would like to add it to the set.

In stackoverflow, the official documentation and here ACL functions are suggested as possible solutions like Merge/Merge_Recursive and Union.
The examples are simplistic, don't use nested documents, and to cryptic for a newbie. 

The final ACL update might need a HAS function to check existence of the attribute. Had to create it to test a Union example.

What is the correct syntax, with the relevant functions for the $update? I had no success with different dots, commas, curly brackets, braces etc.?

Everyday I'm liking Arangodb more and more and Jan thank you for the Php driver.

Jan Steemann

unread,
Oct 24, 2014, 11:01:51 AM10/24/14
to aran...@googlegroups.com
Hi there,

I took a two-step approach for this:

First of all, as there is no pre-defined addToSet function, I registered
an AQL user function named "my::addToSet" via the ArangoShell:

var aqlfunctions = require("org/arangodb/aql/functions");
var addToSet = function (previous, toAdd) {
if (previous === undefined ||
previous === null ||
! Array.isArray(previous)) {
/* initial value for the set */
return [ toAdd ];
}

/* compare each existing element against toAdd */
var compare = JSON.stringify(toAdd);

for (var i = 0; i < previous.length; ++i) {
if (JSON.stringify(previous[i]) === compare) {
/* toAdd is already in the set */
return previous;
}
}

/* toAdd is not yet in the set. now add it */
previous.push(toAdd);
return previous;
});

aqlfunctions.register("my::addToSet", addToSet);


After that, the function is callable from AQL via my::addToSet(), for
example using this query:

FOR p IN profiles
FILTER p.doc == @doc && p._key == @key

LET contacts = my::addToSet(p.detail.cnx.e, @data)
LET detail = { cnx: { e: contacts } }

UPDATE p WITH {detail: detail} IN profiles


I used the following bind parameters to call it:

{
"doc": "profile",
"key": "81855392035",
"data": {
"name": "John Doe",
"at": "pe...@test.com",
"type": "private3"
}
}

I think this does what was required. Please let me know if this is
working for you.

Thank you and best regards
Jan
> --
> You received this message because you are subscribed to the Google
> Groups "ArangoDB" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to arangodb+u...@googlegroups.com
> <mailto:arangodb+u...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.

Jan Steemann

unread,
Oct 24, 2014, 11:04:22 AM10/24/14
to aran...@googlegroups.com
> Everyday I'm liking Arangodb more and more and Jan thank you for the Php
> driver.

Good to read. And we have to thank @frankmayer
(https://github.com/frankmayer), as he has done most of the commits for
the PHP driver after I originally wrote it.

Thanks!

Maxwell Smith

unread,
Oct 26, 2014, 5:58:04 AM10/26/14
to aran...@googlegroups.com
Guten Tag

I'm eager to try out the given solution but I'm stuck in step 1.
Seems like I'm unable to register a function.

My steps:
Opened the Web Interface JS Shell (my first time) and created the
aqlfunctions var.
Typing in the name of the variable shows me the methods available for
the object: unregister, register etc.


I copied my steps from the shell, using an example from the documentation:
JSH> var aqlfunctions = require("org/arangodb/aql/functions");
JSH> aqlfunctions
==> { "unregister" : function (name) { ... }, "unregisterGroup" :
function (group) { ... }, "register" : function (name, code,
isDeterministic) { ... }, "toArray" : function (group) { ... } }

JSH> var tempC = function (celsius){ return celsius * 1.8 +32;};
JSH> aqlfunctions.register("myfunc::tempC", tempC);
[ArangoError undefined: ]


I've tried numerous examples and end up with the same error.
I'm I doing something stoopid or do I need to config/init something
before I'm able to use the shell for functions as nobody is
experiencing a similar error in the community forums.

My stats (ask if you need more): Windows 64bit, arango 2.2.4, firefox browser.

Thanx
> You received this message because you are subscribed to a topic in the
> Google Groups "ArangoDB" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/arangodb/dNVkK-GF6mA/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> arangodb+u...@googlegroups.com.

Jan Steemann

unread,
Oct 27, 2014, 5:52:47 AM10/27/14
to aran...@googlegroups.com
Hi there,

I am currently looking into it and will post my findings here.
All I can say so far is that it works from the ArangoShell
(arangosh.exe) without problems, but not from the browser-based UI.

Best regards
Jan

Jan Steemann

unread,
Oct 27, 2014, 6:41:58 AM10/27/14
to aran...@googlegroups.com
Hi,

registering AQL user functions via the web UI (JS Shell) did not work
properly in 2.2. I have fixed that in the 2.2 and devel branches. The
fix will be contained in the upcoming releases.

For now, you may use the ArangoShell (arangosh.exe) to register AQL user
functions. It seems to be working ok with it.

Best regards
Jan

Maxwell Smith

unread,
Oct 27, 2014, 11:15:38 AM10/27/14
to aran...@googlegroups.com
Hi Jan

Thank you for the solution, I like the flexible approach and it worked
by registering the function with arangosh.

The forum responses are always quick, honest and courteous, kudos to
Frank and the team.

Kind Regards
Maxwell
Reply all
Reply to author
Forward
0 new messages