Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arangodb LET variable from AQL for use it in FILTER

I have collection 'Notifier'. Given the following example document of this collection:

{
  "timestamp": 1413543986,
  "message": "message",
  "readed": {
    "user_8": 0,
    "user_9": 0,
    "user_22": 0
  },
  "type": "1014574149174"
}

I try find this document with the following AQL:

FOR n IN Notifier
LET usersFound = TO_BOOL(
        FOR user IN n.readed
        FILTER user == 'user_8'
        LIMIT 1
        RETURN user
    )
FILTER usersFound==true
RETURN n

I get the following error:

[1501] syntax error, unexpected FOR declaration, expecting ) near 'OR user IN n.readed FILT...' at position 3:10

How can I write this AQL correctly using LET?

like image 944
VasiliyKobzev Avatar asked Oct 21 '14 14:10

VasiliyKobzev


2 Answers

Your query is almost correct, there are 2 minor issues.

1) TO_BOOL() are chars to trigger the correspoding function, you now want to insert a subquery, that is triggered by wrapping an AQL statement in additional (). So instead of TO_BOOL(AQL) you have to use: TO_BOOL((AQL));

2) n.readed is a JSON object, FOR x IN expectes a list. As you are iterating over the Attributes of n.readed you can use ATTRIBUTES(n.readed) here.

Here is the correct solution for your example:

FOR n IN Notifier
LET usersFound = TO_BOOL(
        (FOR user IN ATTRIBUTES(n.readed)
        FILTER user == 'user_8'
        LIMIT 1
        RETURN user)
    )
FILTER usersFound==true
RETURN n

PS: If you are only looking for the exisence of an attribute and do not want to do further filtering you can get that a bit easier using HAS:

FOR n IN Notifier
LET usersFound = HAS(n.readed, 'user_8')
FILTER usersFound==true
RETURN n
like image 100
mchacki Avatar answered Sep 27 '22 23:09

mchacki


If you are just looking for a presence of some field which value can be converted to boolean value you don't need to bother with LET and subqueries. Following query uses HAS function to determine presence of specified field inside document and BOOL to convert it's value to boolean representation:

LET search = 'user_8'
FOR n IN Notifier
    FILTER HAS(n.readed, search) == true && TO_BOOL(n.readed[search])
    RETURN n
like image 28
yojimbo87 Avatar answered Sep 28 '22 00:09

yojimbo87