Intersect between all the nodes in Graph

Hi, I have 3 vertex
a) Person
b) School
c) Company
Person is connected to School and
Person is connected to Company But
School and Company are not connected.
I want to filter out the person, his School, and his company
Please note I want to traverse from Person only

I could use simple queries as
school_res = select p.name, s.name from Person:p-()-School:s where p == ‘Jon’;
company_res = select p.name, c.name from Person:p-()-Company:c where p == ‘Jon’

I want to know if there is any efficient way. because, going forward more nodes may be added, is there any one-liner? like an intersection or something?

Hi @akashkarothiya ,

I believe you can do something like this in TigerGraph to specify that you want all the 1-hop connections from Person.

    all_1_hop = SELECT t FROM Person:p -(:e)- :t WHERE p == "Jon";
    PRINT all_1_hop;

Please let me know if this helps in your use case.

Also, I’d recommend specifying a vertex_set for more efficiency. See here (SELECT Statement :: GSQL Language Reference) for more details.

So, your function can look like this.

CREATE QUERY get_all_connections_to_person(VERTEX<Person> p) FOR GRAPH <graph-name-here> {
    start_person = {p};
    all_1_hop = SELECT t FROM start_person:p -(:e)- :t;
    PRINT all_1_hop;
}

Then, when you call the function, you can pass in “Jon” as a Person vertex. By not having a WHERE clause to search through all person vertices to find Jon, it’ll make it more efficient.

Best,
Supawish Limprasert (Jim)

1 Like

Hi Jim, Thank you for your quick response. This worked.
However, I did not understand what is the significance of :e and :t , are these reserved keywords? Could you please share the documentation URL for this if possible?
Meanwhile, i found an alternative way in the docs - Conjunctive Pattern Matching

SELECT p.name, s.name, c.name INTO cp FROM Person:p-()-School:s,Person:p-()-Company:c
WHERE p == "Jon";
PRINT cp ;

Let me know your thoughts on this.

Hi @akashkarothiya ,

It’s nice that you found a different way to do it! I haven’t tried the SELECT ... INTO <table-name> syntax yet, but that seems like one good way to gather information into some table-like format. I also haven’t tried out the Conjunctive Pattern Matching yet, though looking at the information for it, it can be helpful if you want to intersect results from different patterns and combine them.

One thing to be aware of for Conjunctive Pattern Matching was, it might give a different result than the one-hop pattern below that I showed you. For instance, in the Conjunctive Pattern Matching in your case, I believe the person being shown needs to have both School and Company connections. If they only have a School connection, the table you select into might be empty (which could be what you want). It’s also a beta feature, so if you use it and find something weird going on, please notify us so our engineering team can look at the issue. You’ll have to check into the docs page to be sure: Conjunctive Pattern Matching (Beta) :: GSQL Language Reference

Best,
Supawish Limprasert (Jim)

As for the tutorial with usages of alias, I recommended looking at this one. It’ll also go in more details over how you can utilize different elements of a 1-hop traversal pattern (like filtering): One-hop patterns :: GSQL Language Reference

The :e and :t are alias that can be used to refer to the the edge and the target vertex. Generally, I used the “e” alias for edge, and the “t” alias for “target”. There’s no definite rules around this - you can use any alias/names to refer to the source, edge, and target that makes sense to you.

Basically, what this query

SELECT t FROM start_person:p -(:e)- :t;

means is, it’ll start from start_person vertex/vertices, go to every edge of start_person (any edge type), and from that reaches out to every target vertex (any vertex type).

If you want to specify the type of vertex, you can also do it like below, where it’ll reach out the target vertex of type “Person” or “School”.

SELECT t FROM start_person:p -(:e)- (Person|School):t;

We didn’t get to use e and t alias yet in the above pattern, I just use it so we know which part is an edge and which part is a target. Aliases could be helpful when you do the filtering and gathering information. For instance, suppose you want to gather information about the school names and how they are connected to a person, you can use an accumulator and print the results out.

CREATE QUERY get_all_school_connections_to_person(VERTEX<Person> p) FOR GRAPH <graph-name-here> {
    ListAccum<EDGE> @@edge_list;
    SetAccum<STRING> @@school_name_list;

    start_person = {p};
    all_1_hop = SELECT t FROM start_person:p -(:e)- School:t
        ACCUM
            @@edge_list += e,
            @@school_name_list += t.name;

    PRINT all_1_hop;
    PRINT @@school_name_list;
    PRINT @@edge_list;
}

If you print out the edges, the “visualize graph result” tab would show the shape of the connections! See here for details: Write Queries :: GraphStudio and Admin Portal

You can read more information about the accumulator here: Accumulators Tutorial :: GSQL Language Reference

I hope this helps!

Best,
Supawish Limprasert (Jim)