Simple path query

I’m trying to learn how to write a path query and I want to start with one vertex and show a string (sequence) of vertices after it until we match certain criteria. My graph will represent the words in a paragraph where each word is a vertex and each word will be linked to only one before and one after (except for the first and last words).

The vertex of type “word” has an attribute called “Text”

Below is my starter code for this query. It passes in the starting vertex (word) and we want to return all the vertices in a path to the first instance of a word where it’s “Text” attribute has a value of “width”.

CREATE QUERY wordpathtest(vertex<word> w) for graph social {

    // value to fetch the starting word - 11175600
    // "width" is the word we want to end with in the path
  SetAccum<edge> @@edgeSet;

  Start = {w};
  Result = select t from Start:s - (nextword:e) - word:t
             WHERE  t.Text == "width"
           accum @@edgeSet += e;

    print Result;
  print @@edgeSet;
}

Can you please show me how to revise this so it follows the path described?

If it’s any help, below is the json from the query in it’s current state (I should have named the attributes “from…” and “to….” To source and target.

Thank you.

I looked here but didn’t find an example showing how i could fix my code.

https://docs.tigergraph.com/dev/restpp-api/built-in-endpoints#path-finding-algorithms

[
  {
    "Result": [
      {
        "v_id": "11175601",
        "v_type": "word",
        "attributes": {
          "Text": "“Property”)"
        }
      }
    ]
  },
  {
    "@@edgeSet": [
      {
        "e_type": "nextword",
        "from_id": "11175600",
        "from_type": "word",
        "to_id": "11175601",
        "to_type": "word",
        "directed": false,
        "attributes": {}
      }
    ]
  }
]

Hi George,

You can use a WHILE loop : https://docs.tigergraph.com/dev/gsql-ref/querying/control-flow-statements#while-statement

You’ll need to make some changes for the while loop to work:

CREATE QUERY wordpathtest(vertex w) for graph social {

// value to fetch the starting word - 11175600
// "width" is the word we want to end with in the path

SetAccum @@edgeSet;

Start (ANY) = {w};

While (condition goes here) do
Start = select t from Start:s - (nextword:e) - word:t

         WHERE  t.Text == "width"
       accum @@edgeSet += e;

end;
print Result;
print @@edgeSet;
}

I changed the Result vertex to Start, otherwise you’d be selecting from Start within the loop.

Thanks,
Kevin

Thanks Kevin.

In your sample code:

“While (condition goes here) do”

the condition would be "t.Text != “width”

but “t” is declared after this line. So I tried to declare a variable for the vertex “word” before and set it in the loop but the docs say
“A local variable can be declared only in an ACCUM, POST-ACCUM, or UPDATE SET clause,”

I’m lost here as my past coding experience doesn’t apply.


I was able to get it to work using a counter in the WHILE loop as shown below for anyone who’s interested. But I would still like to make the WHILE’s condition loop until we find the attribute’s value of “width”.

CREATE QUERY wordpathtest2(vertex<word> w) for graph social {


    // value to fetch the starting word - 11175600
    // "width" is the word we want to end with in the path
  SetAccum<edge> @@edgeSet;
	INT ite = 0;
  Start (ANY) = {w};

  WHILE  ite < 5 DO
    Start = select t from Start:s - (nextword:e) - word:t
          //WHERE  t.Text == "width"
          ACCUM @@edgeSet += e;
	  ite = ite + 1;
  END;
  print Start;
  print @@edgeSet;
}

Hi George,

Here is the documentation for the WHILE loop: https://docs.tigergraph.com/dev/gsql-ref/querying/control-flow-statements#while-statement

Try using this as an example:

CREATE QUERY word(vertex input) FOR GRAPH MyGraph {

  1. string hello;

SetAccum @@edgeSet; // print path

Start (ANY) = {input};

  1. while hello != “width” do

Start = select t from Start:s-(nextword:e)-word:t

      accum @@edgeSet += e, 
  1.                           **hello = t.attribute;**
    

end;

  1. print hello , @@edgeSet;

}

  1. I declared a variable hello at the top.

  2. Set the while condition to match a specific string.

  3. Update the value of variable hello within the ACCUM clause during traversal

  4. Print the variable just to make sure it’s correct.

This should work.

Also, when using the WHILE loop, we can use LIMIT to constrain the number of iterations the WHILE loop takes. This is a lot more convenient than creating and incrementing a counter.

e.g.

WHILE condition LIMIT 5 do

do stuff here

end;

I was able to get a while loop to work using an integer counter, but with the logic using “width”. Your code sample did not compile and below is a screenshot of the compile error.

Where “t.Text” is the vertex attribute that will contain the value “width”.

Thank you

Hey George,

The t.Text I used was under the assumption that the vertex identifier was named Text .

If you set up the schema to use the primary id as an attribute, you can change the “Text” part to whatever you named the primary id and it should work.

Thanks,

Kevin

Hi Kevin,

I’m assuming primary keys in TG must be unique as they are in other databases. If this is true then - Since a sentence can repeat the same word many times the word’s text cannot be used as a primary key. We imported all of the words into an sql table where each word has an integer PK value. we took data from this table, imported it into a csv file and imported that into this TG solution.

Can’t we test the value “width” with an the attribute named Text in this loop?

Also, this still doesnt address the compile error “The vertex set or edge attribute outside a DML block cannot be referred.”

I moved the line inside the block and that doesnt compile, and I googled this error and found nothing. Sorry for all the questions, but not finding code examples or documentation on how to do this makes this difficult to learn.

Thank you for any help you can offer.

Hi George,

Yes, primary id/key must be unique, and yes you can store the words as an attribute on each word vertex.

This error is because you placed the line outside the ACCUM clause. After accumulating the edgeset, don’t use a semicolon if you’re including multiple statements. The semicolon signifies the end of the select block.

Thanks,

Kevin

worddata.png

and the current query:

CREATE QUERY wordpathtest3(CREATE QUERY wordpathtext3(vertex w) for graph social {

// value to fetch the starting word - 11175600

string hello;
SetAccum @@edgeSet;

Start (ANY) = {w};

WHILE hello != “width” do

Start = select t from Start:s - (nextword:e) - word:t

      ACCUM @@edgeSet += e,

hello = t.Text;

END;
print Start;
print @@edgeSet;
}

Great Thanks Kevin,

Now it compiles and runs. however, it must be in an endless loop as it times out after 16 seconds which brings us to 2 problems/questions.

  1. this vertex (id=11175600) is linked to a linear string of about 200 other vertecies. I think the loop should end at that point if it doesnt find the matching criteria. If I’m wrong (which I think i am) then what logic to we add to end the loop when we reach the end of linked verticies?

  2. we should have found the condition to end the loop in 11 loops. below is a screenshot of the exact data we’re working with starting with the source vertiex id=11175600. Vertix id=11175611 has an attribute “Text” with a value of “width” which is the condition to end the loop. Can you tell me what went wrong?

Thank you.

Looking at your schema again, since there should be a specific flow of the order of words, you’ll need to change the nextword edge to be directed. If we make this change, we won’t need to check for the end of the linked vertices because we will not be able to traverse “forward” anymore.

The reason why there is an endless loop is because the current edge is undirected, so it can also travel backwards.

I mistakingly assumed your schema was already using a directed edge between words - make this small change and it should be fine.

Thanks,

Kevin

You are right the “directed” checkbox was not checked. I checked it and tried to upload the modified schema but got the error msg below which basically says that each query dependent on this change will be uninstalled. OK. But when I look at this edge again in edit mode the directed checkbox is unchecked. Likewise when I look at the queries the button to install them is enabled which tells me they were uninstalled. At this point it doesnt want to let me make the edge directed - it wont save the changes.

Error

Using graph ‘social’ The job local_schema_change_yoDS8n4Ryp is created. Current graph version 17 Trying to drop the edge nextword. Validating existing queries… Type Check Error in query wordpathtext3 (TYP-152): line 8, col 37 ‘nextword’ is neither a parameter nor a global accumulator, and it is not an edge type in the graph schema. The query wordpathtext3 will be uninstalled after schema update, please update it. Type Check Error in query paragraphWordTest (TYP-152): line 6, col 36 ‘nextword’ is neither a parameter nor a global accumulator, and it is not an edge type in the graph schema. The query paragraphWordTest will be uninstalled after schema update, please update it. Type Check Error in query wordtest (TYP-152): line 6, col 38 ‘nextword’ is neither a parameter nor a global accumulator, and it is not an edge type in the graph schema. The query wordtest will be uninstalled after schema update, please update it. Type Check Error in query wordpathtest2 (TYP-152): line 10, col 37 ‘nextword’ is neither a parameter nor a global accumulator, and it is not an edge type in the graph schema. The query wordpathtest2 will be uninstalled after schema update, please update it. The query hello2 will be uninstalled after schema update, please update it. The query hello will be uninstalled after schema update, please update it. The query Qry2 will be uninstalled after schema update, please update it. The query paragraph2word will be uninstalled after schema update, please update it. Type Check Error in query wordpathtest (TYP-152): line 12, col 38 ‘nextword’ is neither a parameter nor a global accumulator, and it is not an edge type in the graph schema. The query wordpathtest will be uninstalled after schema update, please update it. The query Qry1 will be uninstalled after schema update, please update it. Load job load_job_TigerGraphTestData_2019_09_28_A_Word_csv_1569897648703 will be deleted after schema change. Kick off job local_schema_change_yoDS8n4Ryp Fail to run job local_schema_change_yoDS8n4Ryp, nothing changed.

Hi George,

I’m going to send you a zoom call link.

George,

The reason why the schema change was failing is because of the infinite loop. Your system has been restarted and now you should be able to proceed.

Let us know if you have any further questions.

Thanks,

Kevin

OK it saves now. I had to update the “map data to graph” tab.

The query no longer required saving and it still times out.

Just to be clear, hears the query in it’s current state:

CREATE QUERY wordpathtext3(vertex<word> w) for graph social {
    // value to fetch the starting word - 11175600
 string hello;
  SetAccum<edge> @@edgeSet;
  Start (ANY) = {w};
  WHILE hello != "width" do
    Start = select t from Start:s - (nextword:e) - word:t
          ACCUM @@edgeSet += e,
          hello = t.Text; 
  END;
  print Start;
  print @@edgeSet;
}