How to SELECT a single vertex

What is the query syntax to select a single vertex - person for example by passing in:
VERTEX p
or
STRING id

This example does not use a WHERE clause and appears to return more than one person.

  Start = {p};
  Result = SELECT tgt
           FROM Start:s-(friendship:e) ->person:tgt;
  PRINT Result;

Thank you.

Hi @gpadvorac

To pass a person param VERTEX<person> p

Full Example Based on Question:

CREATE QUERY hello(VERTEX<person> p) FOR GRAPH social{

Start = {p.*};

Result = SELECT tgt
              FROM Start:s-(friendship:e) ->person:tgt
              WHERE s == p;

PRINT Result;

Does this make sense?

Thanks. This is so Non-Intuitive for me. Friendship is the link from one person to another. My brain says “select * from person where person == p”, but enough of my brain…

I thought I could make this work translating the “person” example to our graph where we don’t have a person or friendship. We have a User and we don’t link users to users which breaks this example. My bad for trying to use person.

image

We have an edge called User2Round if that’s any help but it seems a lot cleaner just to query User. Any more recommendations?

Are you literally looking to get back the person vertex? I’m confused by the friendship stuff.

My head is saying this, but I guess I’m missing an important point:

Result = select pv from Start:pv ;

Hi Richard,

Re “I’m confused by the friendship stuff.”, that was taken from the only example I could find that was returning a person - bad example…

Yes, I want to return a single vertex. there may be a situation where I have a vertex ID and need the vertex to read it’s attributes or for some other reason.

You example works and helps give me perspective on things.

Thank you.

OK good! You are not alone on working through the mechanics of getting the attributes out of vertex parameters.

It really isn’t obvious (well it wasn’t to me) that the vertex-set we get from the Start={p} statement isn’t actually useful outside a SELECT statement.

They can be printed directly, as PRINT p does some implicit magic, but that’s all.

There are more tricks needed if you pass a string for a vertex id that doesn’t exist as the obvious WHERE clause approach is really slow. I covered that elsewhere, and it is not what you asked so I won’t elaborate unless you have an interest, but FYI.

Are you saying WHERE clauses in general are slow?

They can be slow (and I mean TigerGraph slow, which is still quicker than most)

WHERE clauses are implemented as filters, so unless an explicit secondary index is defined (3.x I believe, though it might be stealthed in earlier), you scan the entire list of vertices/edges in the traversal.

Usually that is okay, but for some specific cases (like selecting individual vertices by attribute) it really isn’t.

1 Like

OK thank you the helpful information!

This is one place where previous SQL experience helps. What you want works exactly the same way as regular SQL:

GSQL-Dev > USE GRAPH social
Using graph 'social'
GSQL-Dev > SELECT *  FROM person WHERE name == "Tom"
[{
  "v_id": "Tom",
  "attributes": {
    "gender": "male",
    "name": "Tom",
    "state": "ca",
    "age": 40
  },
  "v_type": "person"
}]

This also one of the Built-In Queries (IHMO, a confusing term and doesn’t fully hint at the traps you can fall into…)

In the GSQL 101 example, the name is the primary index, so it return just one vertex.

However, there is an inconsistency, where the JSON returned refers to the primary_id as v_id (ugh!)

GSQL-Dev > SELECT *  FROM person WHERE v_id == "Tom"
Semantic Check Fails: The attribute v_id doesn't exist in vertex type person
GSQL-Dev > SELECT *  FROM person WHERE primary_id == "Tom"
[{
  "v_id": "Tom",
  "attributes": {
    "gender": "male",
    "name": "Tom",
    "state": "ca",
    "age": 40
  },
  "v_type": "person"
}]
1 Like

It’s a good point.

v_id won’t go away as it is intrinsic to the way TG works, and is effectively metadata.

To get the primary_id attribute (or however it is defined) returned you need to set the “PRIMARY_ID_AS_ATTRIBUTE” in the schema. That should bring it closer to what you expect.

I would recommend what Neo4J’s Cypher does, which avoids the problem of what if the DB happens to choose v_id or primary_id as a column name?

In Cypher, there’s a special function that gets the internal ID of the vertex. The rough equivalent would be:

id(node) == "Tom"

BTW, the downside of Neo4J’s internal ID, is they recycle them, so it’s a bad idea to hang on them, so having an explicit key definition in TG is superior.

The other point I would make, is having v_id and primary_id increases the cognitive load of having to learn TG. There’s enough complication as it is. No one thing is going to make or break the usability, but in total I have found enough TG stumbling blocks that my progress in learning has been impeded. It probably took me a week to make progress in TG vs. maybe a few hours with Neo4J.

There’s still a lot that mystifies me, but unfortunately, my adventures with TG will have to go on the back burner for now.

1 Like