Hot questions for Using Cassandra in gremlin

Question:

g.V().has(label,"request_job").order().by("submit_time",incr).valueMap("submit_time")

==>[submit_time:[1330647978000]]
==>[submit_time:[1330652298000]]

When I use, order() query in Gremlin console, it is working fine. But when I try the same query in Java, I am not able to use "incr", it is showing that undefined symbol "incr".

How to use "incr" with order() in Java?

Kindly help me to resolve this problem.


Answer:

It is defined in the enum Order (javadoc) which is automatically imported by the Gremlin Console. You should add the following import to your Java class:

import static org.apache.tinkerpop.gremlin.process.traversal.Order.*;

Question:

{
    Vertex person1 = titanGraph.addVertex(null);
    person1.setProperty("userId", 1);
    person1.setProperty("username", "abc");


    Vertex person2 = titanGraph.addVertex(null);
    person2.setProperty("userId", 2);
    person2.setProperty("username", "bcd");


    Edge knows = titanGraph.addEdge(null, person1, person2, "Knows");
}

I have created two vertex(person1,person2) and edge("knows") between them using JavaAPI. After some time, I want to add vertex(person3). How can I create edge("knows") between person1 and person3 using JavaAPI? Kindly help me to resolve this problem.


Answer:

Here is one way using Titan 1.0.0 and Apache TinkerPop 3.0.1 APIs:

 // lookup existing person1 by userId
 GraphTraversalSource g = titanGraph.traversal();
 Vertex person1 = g.V().has("userId", 1).next();

 // create person3
 Vertex person3 = titanGraph.addVertex("Person");
 person3.property("userId", 3);
 person3.property("username", "cde");

 // create edge from person1 to person3
 Edge knows = person1.addEdge("Knows", person3);

Please refer to the Javadocs for Titan 1.0.0 and Javadocs for TinkerPop 3.0.1. See also this basic Titan + TinkerPop Java example program for more ideas.

The syntax is different if you are using an older version of Titan, such as 0.5.4, which the code in your question appears to be using. If you are starting a new project, you should be using 1.0.0.

Question:

GraphTraversal<Vertex, Map<String, Object>> tsList = traversalSource.V().has("request","id_key",114).valueMap();        
while(tsList.hasNext())
{
System.out.println(tsList.next().get("status")); //prints result
System.out.println(tsList.next().get("tree_id_key")); //prints result
System.out.println(tsList.next().get("username")); //here throws Exception for any vertex.
System.out.println(tsList.next().get("tree_status"));
}

when I run the above query, I am getting values for any first and second propertyKey. but after getting answers for two Keys It throws NoFastSuchElementException for any propertyKey...Kindly help me..how can I resolve this?

but using below query I am able to get the answer:

GraphTraversal<Vertex, Map<String, Object>> tsList = traversalSource.V().has("request","id_key",114).values("status","tree_id_key","username","tree_status");       
while(tsList.hasNext())
{
System.out.println(tsList.next());//prints "status" value
System.out.println(tsList.next());//prints "tree_id_key" value
System.out.println(tsList.next());//prints "username" value
System.out.println(tsList.next());//prints "tree_status" value
}

updated:

GraphTraversal<Vertex, Map<String, Object>> ts = traversalSource.V().has("request","id_key",113).valueMap();        
while(ts.hasNext())
{
Map<String, Object> tsList=ts.next();
SuiteIdKey=(long)((ArrayList)tsList.get("suiteKey")).get(0);
seqe=(int)((ArrayList)tsList.get("sequence")).get(0);
}

In the above query, ts will return many rows and for each row I will get suiteIdkey,seqe..I am able to get the answer. But tsList is Map<>, it is not directly returning answer when I use like this =(long)tsList.get("suiteKey"), without ArrayList. Is it the correct way? Kindly help me.


Answer:

You are asking for two different things in those two traversals. The first one with valueMap() asks that the vertex be converted to a Map, so you don't want to keep calling next() in that loop. Just do:

Map<String, List<Object>> m = traversalSource.V().has("request", "id_key", 114).
                                                  valueMap().next();        
System.out.println(m.get("status").get(0)); 
System.out.println(m.get("tree_id_key").get(0)); 
System.out.println(m.get("username").get(0)); 
System.out.println(m.get("tree_status").get(0));

Keep in mind above that i'm assuming your traversal always returns one vertex...account for that otherwise if that is not true.

In your second traversal where you do values() you are asking Gremlin to convert grab the values of those specific properties on that vertex and stream them out and thus you need to iterate with multiple calls to next.

Note that typically returning the entire vertex object isn't a recommended practice. It is somewhat akin to SELECT * FROM table in SQL. It is better to get only the fields that you want to get which then gets rid of the ugly multi-property issue of Map<String, List<Object>>:

Map<String, Object> m = traversalSource.V().has("request", "id_key", 114).
                                            project('s`,'tik', 'u', 'ts').
                                              by('status').
                                              by('tree_id_key').
                                              by('username')
                                              by('tree_status').
                                            next();        
System.out.println(m.get("s")); 
System.out.println(m.get("tik")); 
System.out.println(m.get("u")); 
System.out.println(m.get("ts"));

Question:

Each vertices and edges has following properties:

Request [req_id: long, submit_time:long, priority:int, status:char]  
Test_B [tb_id: long, tb_name: string]  
TestSuite [suite_id: long, Suite_Status: char]  
Edge-A [sequence_num: int]  
Edge-B [ sequence_num: int, suite_status: char] 

Relationship between vertices and edges:

Request----EdgeA----Test-B  
Request----EdgeB----TestSuite  
TestSuite----EdgeC----Test-B  

Below query is ordering(submit_time from request) in ascending order and will display the TestSuite details:

g.V().order().by("submit_time",incr).outE("Edge-B").
  has("suite_status","Q").inV().valueMap() 

Here is an example graph:

rj1=graph.addVertex(label,"request","req_id",1138,"status","S","priority",3,"submit_time",1330647978000)
rj2=graph.addVertex(label,"request","req_id",1133,"status","S","priority",2,"submit_time",1330662012000)
rj3=graph.addVertex(label,"request","req_id",1136,"status","S","priority",1,"submit_time",1330652298000)
rj4=graph.addVertex(label,"request","req_id",1135,"status","S","priority",1,"submit_time",1330666768000)

ts1=graph.addVertex(label,"test_suite","test_suite_id",8713)
ts2=graph.addVertex(label,"test_suite","test_suite_id",8718)
ts3=graph.addVertex(label,"test_suite","test_suite_id",8688)
ts4=graph.addVertex(label,"test_suite","test_suite_id",8729)

tb1=graph.addVertex(label,"test_b","tb_id",574)
tb2=graph.addVertex(label,"test_b","tb_id",573)
tb3=graph.addVertex(label,"test_b","tb_id",577)


e1=rj1.addEdge("edgeB",ts1,"sequence",1,"job_suite_status","Q")
e2=rj1.addEdge("edgeB",ts2,"sequence",2,"job_suite_status","Q")
e1=rj2.addEdge("edgeB",ts1,"sequence",1,"job_suite_status","Q")
e2=rj2.addEdge("edgeB",ts3,"sequence",2,"job_suite_status","Q")
e1=rj3.addEdge("edgeB",ts4,"sequence",1,"job_suite_status","Q")
e2=rj3.addEdge("edgeB",ts2,"sequence",2,"job_suite_status","Q")
e1=rj4.addEdge("edgeB",ts3,"sequence",1,"job_suite_status","Q")
e2=rj4.addEdge("edgeB",ts4,"sequence",2,"job_suite_status","Q")

e1=rj1.addEdge("edgeA",tb1,"sequence",1)
e2=rj1.addEdge("edgeA",tb2,"sequence",2)
e3=rj2.addEdge("edgeA",tb1,"sequence",1)
e4=rj2.addEdge("edgeA",tb1,"sequence",2)
e5=rj3.addEdge("edgeA",tb2,"sequence",1)
e6=rj3.addEdge("edgeA",tb3,"sequence",2)
e7=rj4.addEdge("edgeA",tb3,"sequence",2)
e8=rj4.addEdge("edgeA",tb1,"sequence",1)

Here, rj1, rj2, rj4 is connected to tb1(edgeA): so for each test_b (example: tb_id=574), sort request(rj1,rj2,rj4) based on submit_time and take test_suite_id and sequence.

Finally I need to print test_suite_id, sequence, and corresponding req_id. Kindly help me to resolve this. Thanks.


Answer:

It helps to label steps with as() and then use select() to prepare the result.

g.V().has("tb_id", 574).
  in("edgeA").dedup().as("r").
  order().by("submit_time", Order.incr).as("st").
  outE("edgeB").has("job_suite_status", "Q").as("s").
  inV().as("t").
  select("t", "s", "r", "st").
    by("test_suite_id").by("sequence").by("req_id").by("submit_time")

Start from the test with tb_id 574, then traverse to its requests (label as r), order the requests by submit time (label as st), traverse to the sequences (label as s), finally traverse to the test suites (label as t).

Use select() to prepare the result output and by() to pick the properties: test suite, sequence, request, and submit time.

Question:

public class a {
    private static TitanGraph titanGraph = null;
    static GraphTraversalSource traversalSource = null;
public static void main(String a[])
{
    titanGraph = TitanFunctions.getTitanGraph();
    traversalSource = titanGraph.traversal();
    // Task to be executed by each thread
    Runnable r = new Runnable() {
        public void run() {

            long ab = traversalSource.V().has("RequestJob", "RequestId", 203)
                    .has("JobLockStatus","F")
                    .property("JobLockStatus", "B").count().next();
            titanGraph.tx().commit();
            System.out.println("value: "+ab+" : " +Thread.currentThread().getName());
        }
    };
    Thread t1 = new Thread(r, "T1");
    Thread t2 = new Thread(r, "T2");
    t1.start();
    t2.start(); 
    }}

In the above program, Two concurrent threads are trying to update the value..from "F" to "B" for the same RequestId=203. It seems like both threads are getting the status value as "F" and updating it to B. But I want only one thread should change the value from "F" to "B". After updating the value , I have used commit() also to save the changes. If any thread changed the status from "(F)ree" to "(B)usy"..and other thread should see the changed value..("B"). Kindly help me to resolve this.


Answer:

You could use a mutex or a synchronized() block to ensure only one thread can perform that operation at any given time. Something like the following may work:

titanGraph = TitanFunctions.getTitanGraph();
traversalSource = titanGraph.traversal();
Runnable r = new Runnable() {
    public void run() {
        synchronized(titanGraph){
            long ab = traversalSource.V().has("RequestJob", "RequestId", 203)
                .has("JobLockStatus","F")
                .property("JobLockStatus", "B").count().next();
            titanGraph.tx().commit();
        }    
    }
};
Thread t1 = new Thread(r, "T1");
Thread t2 = new Thread(r, "T2");
t1.start();
t2.start(); 

So the above block synchronized(titanGraph) is basically stating that for whatever is inside that block it can only executed by a thread that has the lock on the object within the brackets. In this case the titanGraph. If a thread does not have the lock then it waits for the lock to become available.

Here is a really nice tutorial on using synchronized