Trying to print full detail of vertices nested in a set of vertices

Hi,

I am trying to create a query that will return a list of Posts that a User has authored. A Post can be shown to other Users and/or a Grouping of Users. This is the code for my query which works, but I am unable to figure out how to get all the attributes for Users and Grouping also included in my results in addition to the vertex ids.

QUERY

CREATE QUERY getMyPosts(STRING uid) FOR GRAPH Rex SYNTAX V2{
SetAccum<VERTEX> @groupingSetAccum;
SetAccum<VERTEX> @userSetAccum;

me = SELECT m
FROM User:m
WHERE m.uid == uid;

posts = SELECT p
FROM me -(authors>)- Post:p;

posts2 = SELECT p
FROM posts:p -(show_to>)- Grouping:g
ACCUM p.@groupingSetAccum += g;

posts3 = SELECT p
FROM posts:p -(show_to_1>)- User:u
ACCUM p.@userSetAccum += u;

results = posts UNION posts2 UNION posts3;

PRINT results[results.@groupingSetAccum AS groups, results.@userSetAccum AS users, results.title AS title, results.description AS description];
}

OUTPUT

[
{
“results”: [
{
“attributes”: {
“description”: “Carbonite web goalkeeper gloves are ergonomically designed to give easy fit”,
“groups”: [
“662737d4-da5e-42f4-879c-02f0a96058be”
],
“title”: “Gloves”,
“users”: [
“e1392d37-70e2-497e-b99d-501b3b9c743c”,
“bf15e203-79a7-4ac5-a220-eb7062c32fed”,
“16fa9550-ec27-48cd-b254-b178ba63ba9c”
]
},
“v_id”: “f66d7eef-b41c-4f80-828d-65391407b83e”,
“v_type”: “Post”
},
…
]

According to the docs:
“Full details of vertices are printed only when part of a vertex set variable or vertex expression set. When a single vertex is printed (from a variable or accumulator whose data type happens to be VERTEX), only the vertex id is printed.”

So I was trying to figure out a way to convert the SetAccum into a vertex set variable but always ran into syntax errors. Maybe I’m going about this in the wrong way.

Any help would be appreciated. Thx

Alvin

A couple of quick thoughts:

  1. unless I am misreading this, your UNION isnt actually doing anything for you. since posts2 and posts3 are both results of queries that use posts as the seed set, you arent adding any vertexes, and hence the UNION isnt increasing the size of results, beyond what is already in posts.

  2. if you just want a global list of groupings and users, you could change the queries using posts2 and posts3 to return g and u respectively, then you would have a vertex set of Groupings and Users. Then when you print, you get all the attributes. But I dont think you want that, since you want them to be vertex-attached, not global.

  3. If so, then do you know which attributes from Grouping and User that you want to accumulate? Then you change to using a SetAccum of vertex, to a SetAccum of whatever type is needed for the attribute.

1 Like

Hey Alvin,

In your case, it is crucial to distinguish between a SetAccum< VERTEX > and a VERTEX set.

  • SetAccum< VERTEX > is obtained through explicit accumulator declaration (as you have shown)
  • VERTEX set is the output of a SELECT statement, which contains all targeted vertices that successfully passed the statement. By “targeted vertices”, I mean the vertex type that was specified for collection in the very first part of the statement (known as the SELECT clause).

Here is an example from your code:

posts2 = SELECT p
FROM posts:p -(show_to>)- Grouping:g
ACCUM p.@groupingSetAccum += g;

The targeted vertex type here is posts, as declared by SELECT p and later referenced by posts:p

Your output VERTEX set will thus contain all posts that successfully passed through the statement, and they will be stored in the variable posts2.

Now, if you print posts2, you will be shown the attributes for all posts in the vertex set.

You can implement @groupingSetAccum in this way as follows:

groups = SELECT g
FROM posts:p -(show_to>)- Grouping:g

Notice that SELECT p is now SELECT g

You will also need to modify your posts source VERTEX set to be a single post if you want to mimic the functionality of vertex-attached accumulators (output the relevant groups on a per-post basis).

This seems like more trouble than it’s worth, so I agree with Mark that you should instead accumulate whatever attributes you are concerned with instead of the vertices themselves. If you want to accumulate a lot of attributes, you can TYPEDEF a tuple that basically transfers all the information from the vertex into a custom type that you can access all the components of.

Hi, thx for the response,

  1. The UNION is actually used to combine the results of the @groupingSetAccum and @userSetAccum for each post. I tried putting both accum statements in one SELECT statement but it did not work. So the size of results is meant to stay the same. So if posts2 has Post A with the @groupingSetAccum attribute and posts3 has Post A with the @userSetAccum attribute, the UNION will end up with Post A with both the @groupingSetAccum and @userSetAccum attribute. I discovered this behaviour from trial and error and haven’t seen this documented anywhere as far as I know.

  2. I need local list of groupings and users for each post

  3. I need the attributes to stay tied to the vertex that they belong to. Thx for your thoughts.

Alvin

Hi Alvin, on point 1, it is not the UNION that is giving you the behavior that you are describing. Its true that you can run multiple queries to produce different vertex-attached accumulator values for the same vertex set, but you don’t have to do a UNION to combine them, since they are associated with the vertex itself. You can demonstrate this easily by removing the UNION statement and printing posts.

1 Like

Hi markmegerian,

You are right! I tried printing posts and it gave the same result. Thx for clearing up my understanding of how Tigergraph works.

Alvin

Thx for the response Ishestakov,

I misunderstood markmegerian when he suggested doing a setAccum on the attributes because I assumed he meant accumulating the attributes individually. After you suggested TYPEDEFing a tuple then it made sense. Thanks guys for the guidance!

Regards,

Alvin

Hi,

Suggestion to the Tigergraph team. Please consider an option to print out the attributes if you SetAccum vertices. Kinda strange that only vertex ids are printed. Thx!

Regards,

Alvin

3 Likes

Ishestakov & Markmegerian,

SetAccum on a tuple worked like a charm! Really appreciate the help.

Regards,

Alvin

2 Likes

@alvinchan I have the same problem as you. How did you print out all of the vertex data for your vertices?

What I have right now is simply to define multiple vertex set variables. Unfortunately I need to make the same SELECT multiple times just to get all the data I need:

Start = SELECT s FROM Start:s POST-ACCUM s.@visited = true;

MiddleVertices = SELECT v1 FROM Start:s-(ANY:e1)-one_v_type:v1-(ANY:e2)-two_v_type:v2 WHERE v2.@visited == false;
EndVertices = SELECT v2 FROM Start:s-(ANY:e1)-one_v_type:v1-(ANY:e2)-two_v_type:v2 WHERE v2.@visited == false ACCUM v2.@edges += e1, v2.@edges += e2, @@vertices += v1;

PRINT Start, MiddleVertices, EndVertices;

This is probably the best you can get with the vertex sets. A vertex set can only be formed as the output of a SELECT statement, or using {v_type.*} to obtain a starting set.

As I mentioned above, if you only need a few data points from each vertex, I would recommend accumulating a TUPLE that you TYPEDEF to hold any number of attributes that you need.

1 Like

Hi Justin, I did what Ishestakov recommended which was a setAccum on a TUPLE that I defined. It works however it’s not super elegant.

With Neo4j I can easily print nesting of vertices and corresponding attributes. For example, to print all posts and the user that created it in JSON all I would have to do is the following (p is an alias for Post and u is an alias for User. The .* prints all attributes for that vertex):
RETURN DISTINCT p { ., u {.}}

One other thing, this works for a single level of nesting but I couldn’t figure out a way to get it work for 2 or more levels of nesting. For example, I couldn’t print a Post with the Groupings it’s shown to and the Users that belong to each Grouping along with attributes for each vertex.

Regards,

Alvin

1 Like