Lewis Diamond
Lewis Diamond

Reputation: 24941

ArangoDB - How do you refer to OLD in an upsert statement using AQB

I want to create an upsert statement like this:

upsert {_from: @uid, _to: t._id}
insert { _from: @uid, _to: t._id, like: 1}
update {like: OLD.like+1}
in edge

Using AQB, how do I refer to OLD.like, as an integer and increment by 1?

...
.upsert({_from: '@uid', _to: "t._id"})                                                                                                                                                           
.insert({_from: '@uid', _to: 't._id', like:1})                                                                                                                                                   
.update({like: aqb.get('OLD', aqb.ref('like'))+1})                                                                                                                                               
.in("edge")
...

Upvotes: 1

Views: 270

Answers (2)

stj
stj

Reputation: 9097

As far as I can see it can be achieved like this:

/* search values */
FROM = "v/1";
TO   = "v/2"; 

var qb = require("aqb"); 
q = qb.upsert({ _from: qb.str(FROM), _to: qb.str(TO) })
      .insert({ _from : qb.str(FROM), _to: qb.str(TO), like: 1 })
      .update({ like: qb.plus(qb.get("OLD", qb.str("like")), 1) })
      .in("edge")
      .returnOld("old"); 

/* to verify the generated AQL string */
print(q.toAQL());

This constructs the following AQL query

UPSERT {_from: "v/1", _to: "v/2"} 
INSERT {_from: "v/1", _to: "v/2", like: 1} 
UPDATE {like: (`OLD`["like"] + 1)} IN edge 
LET `old` = OLD 
RETURN `old`

which is hopefully what you were looking for.

Upvotes: 0

Alan Plum
Alan Plum

Reputation: 10902

This actually has nothing to do with UPSERT. The problem is that you're using the plus operator in JavaScript, which tries to convert the expression aqb.get('OLD', aqb.ref('like')) to a string and append '1' to it. In JS operators can't be overloaded, so AQB can't prevent you from doing that.

The correct expression would be aqb.get('OLD', aqb.ref('like')).add(1), which generates the following AQL:

UPSERT {_from: @uid, _to: t._id}
INSERT {_from: @uid, to: t._id, like: 1}
UPDATE {like: (`OLD`[like] + 1)}
IN edge

Also note that this tries to use like as a variable for the name of the attribute. That's probably not what you want. Instead you'd use aqb.str('like') or simply aqb('like') (resulting in OLD["like"]).

You can actually simplify this a bit. OLD.like is a valid simple reference in AQB, so you can simply use aqb.ref('OLD.like').add(1). Or you can simplify it further by using the add function directly: aqb.add('OLD.like', 1). All of these are semantically equivalent and should generate semantically equivalent (if not identical) AQL. Here's the AQL generated by the last example:

UPSERT {_from: @uid, _to: t._id}
INSERT {_from: @uid, to: t._id, like: 1}
UPDATE {like: (`OLD`.like + 1)}
IN edge

Upvotes: 2

Related Questions