Can we collect a variable?

39 views
Skip to first unread message

F21

unread,
May 14, 2013, 6:25:47 AM5/14/13
to aran...@googlegroups.com
I am working on an AQL query to get an activity stream. The format is based on http://activitystrea.ms/
 
I have been successful in getting the stream items, but I am having issues trying to COLLECT them into groups
 
The graph's schema is quite simple
   john--follows-->andy-->activity--actor-->andy
                                         |    |-----object-->post
                                         |---------target-->jane          
 
My AQL currently looks like this:
 
FOR p IN TRAVERSAL(vertices, edges, "vertices/123456", "outbound", {
  "paths": true,
  "strategy": "depthFirst"
})
FILTER p.path.edges[0].`$label` == "follows"  && LENGTH(p.path.edges) == 2

  LET object = FIRST((FOR object in NEIGHBORS(vertices, edges, p.vertex._id, "outbound", [{'$label': 'object'}])
  RETURN object.vertex))
  LET target = FIRST((FOR target in NEIGHBORS(vertices, edges, p.vertex._id, "outbound", [{'$label': 'target'}])
  RETURN target.vertex))
  LET actor = FIRST((FOR actor in NEIGHBORS(vertices, edges, p.vertex._id, "outbound", [{'$label': 'actor'}])
  RETURN actor.vertex))
  LET result = {"activity": p.vertex, "object": object, "target": target, "actor": actor}
 
 RETURN result
 
This returns me a list of activities with their object, target and actor. However, I want to COLLECT and LIMIT the result variable:
 
FOR p IN TRAVERSAL(vertices, edges, "vertices/123456", "outbound", {
  "paths": true,
  "strategy": "depthFirst"
})
FILTER p.path.edges[0].`$label` == "follows"  && LENGTH(p.path.edges) == 2

  LET object = FIRST((FOR object in NEIGHBORS(vertices, edges, p.vertex._id, "outbound", [{'$label': 'object'}])
  RETURN object.vertex))
  LET target = FIRST((FOR target in NEIGHBORS(vertices, edges, p.vertex._id, "outbound", [{'$label': 'target'}])
  RETURN target.vertex))
  LET actor = FIRST((FOR actor in NEIGHBORS(vertices, edges, p.vertex._id, "outbound", [{'$label': 'actor'}])
  RETURN actor.vertex))
  LET result = {"activity": p.vertex, "object": object, "target": target, "actor": actor}
 
  COLLECT a = result.object into g
 
  LIMIT 100
  
 RETURN {"a": a, "g": g}
 
The problem is that the COLLECT actually involves the result from TRAVERSAL. I do not want this at all, and just wish to run COLLECT on the result variable and then LIMIT the collected result. Is there anyway to do this?

Jan Steemann

unread,
May 14, 2013, 7:25:30 AM5/14/13
to aran...@googlegroups.com, F21
Is it possible to do something like this?

FOR result IN (
/* actual query goes here */
)
COLLECT a = result.object INTO g LIMIT 100
RETURN {"a": a, "g": g}


with your example query, that would be:

FOR result IN (
FOR p IN TRAVERSAL(vertices, edges, "vertices/123456", "outbound", {
"paths": true,
"strategy": "depthFirst"
})
FILTER p.path.edges[0].`$label` == "follows" &&
LENGTH(p.path.edges) == 2

LET object = FIRST((FOR object in NEIGHBORS(vertices, edges,
p.vertex._id, "outbound", [{'$label': 'object'}]) RETURN object.vertex))
LET target = FIRST((FOR target in NEIGHBORS(vertices, edges,
p.vertex._id, "outbound", [{'$label': 'target'}]) RETURN target.vertex))
LET actor = FIRST((FOR actor in NEIGHBORS(vertices, edges,
p.vertex._id, "outbound", [{'$label': 'actor'}]) RETURN actor.vertex))

RETURN {"activity": p.vertex, "object": object, "target": target,
"actor": actor}
)

COLLECT a = result.object into g

LIMIT 100

RETURN {"a": a, "g": g}




> --
> 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.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

--
eMail: j.ste...@triagens.de
Telefon: +49-221-2722999-37
Fax: +49-221-2722999-88

triagens GmbH
Br�sseler Stra�e 89-93
50672 K�ln

Sitz der Gesellschaft: K�ln
Registergericht K�ln; HRB 53597

Gesch�ftsf�hrung:
Dr. Frank Celler
Martin Sch�nert
Claudius Weinberger


Diese e-Mail enth�lt vertrauliche und/oder rechtlich gesch�tzte
Informationen. Wenn Sie nicht der richtige Adressat sind oder diese
e-Mail irrt�mlich erhalten haben, informieren Sie bitte sofort den
Absender und vernichten Sie diese e-Mail. Wir haben alle
verkehrs�blichen Ma�nahmen unternommen, um das Risiko der Verbreitung
virenbefallener Software oder e-Mails zu minimieren, dennoch raten wir
Ihnen, Ihre eigenen Virenkontrollen auf alle Anh�nge an dieser e-Mail
durchzuf�hren. Wir schlie�en au�er f�r den Fall von Vorsatz oder grober
Fahrl�ssigkeit die Haftung f�r jeglichen Verlust oder Sch�den durch
virenbefallene Software oder e-Mails aus.

This e-mail may contain confidential and/or privileged information. If
you are not the intended recipient (or have received this e-mail in
error) please notify the sender immediately and destroy this e-mail. We
have taken precautions to minimize the risk of transmitting software
viruses but nevertheless advise you to carry out your own virus checks
on any attachment of this message. We accept no liability for loss or
damage caused by software.

F21

unread,
May 14, 2013, 7:46:14 AM5/14/13
to aran...@googlegroups.com, F21, j.ste...@triagens.de
Hi Jan,
 
That worked! :) Another solution I came up with was to store the inner traversal temporary into a variable using LET. Will using LET to store it result in more memory being used?
 
Cheers :)

Jan Steemann

unread,
May 14, 2013, 7:55:08 AM5/14/13
to F21, aran...@googlegroups.com
LET shouldn't use *much* more memory.
Internally it should create only a reference to the assigned value for
lists and documents. Scalars such as bool(true) or number(2) might be
copied, but this shouldn't take much memory either.

The COLLECT might be much more expensive than the LETs in your queries.
COLLECT will group the values by some criterion, and thus needs to sort
the results first.
Reply all
Reply to author
Forward
0 new messages