Issue
Hi so i am using thee following code :
public Graph graph ;
private HashMap<String, Node> nodes ;
private HashMap<Node, Double> inDegree = new HashMap<Node, Double>();
private HashMap<Node, Double> outDegree = new HashMap<Node, Double>();
private GraphTraversalSource g ;
public TinkerTopGraph(Graph graph) {
this.graph = graph;
this.nodes = new HashMap<String, Node>();
graph = TinkerGraph.open();
g = traversal().withEmbedded(graph);
}
public void addEdge(Node sourceNode, Node destinationNode){
}
}
Inside the function "addEdge" i tried making this :
g.V().hasLabel(sourceNode.toString()).tryNext().orElse(g.addV().next());
g.V().hasLabel(destinationNode.toString()).tryNext().orElse(g.addV(destinationNode.toString()).next());
The problem is that when there is already a vertex inside the GraphTraversalSource with the same string with one of the nodes it doesnt detect it . I tried different technics that i found here .For example i have also tried :
g.V().has(sourceNode.toString()).tryNext().orElse(g.addV().next());
g.V().has(destinationNode.toString()).tryNext().orElse(g.addV(destinationNode.toString()).next());
which i think is the same with the above one since i use only labels.I also tried this :
g.V().has(sourceNode.toString()).fold().coalesce(unfold(),addV(sourceNode.toString()))
g.V().has(destinationNode.toString()).fold().coalesce(unfold(),addV(destinationNode.toString()))
but the problem with this one is it throws a warning and doesnt add any vertices at all. I also tired using :
g.V().has(node.toString).tryNext().orElseGet{
g.addV(node.toString()).next()}
but in this case the command orElseGet{} doesnt work and asks for a supplier type inside it.How can i change a vertex type command into a supplier one?
What can i do in order to check if a vertice with a label already exists and then if it doesnt , to add it?
Solution
Using the air-routes data set, this worked fine for me.
List<Vertex> v =
g.V().has("code","AUS").fold().coalesce(unfold(),addV("airport").property("code","AUS")).toList();
System.out.println(v);
When run, the output is the ID of the existing vertex, which is correct.
[v[3]]
Similarly, when the vertex does not exist
List<Vertex> v =
g.V().has("code","XYZ").fold().coalesce(unfold(),addV("airport").property("code","XYZ")).toList();
System.out.println(v);
correctly creates a new vertex with a system assigned ID.
[v[2cc139cc-8645-9991-4631-6df40d47571c]]
If you compile using -Xlint:unchecked
you will see a warning, but the code works. Java Generics and Gremlin do not always play well together and it is often sufficient to either ignore or override the warning using @SuppressWarnings(“unchecked”)
. Sometimes it is possible to create the appropriate generic tags in the query, but given the variable nature of Gremlin results, that is not always possible.
X.java:62: warning: [unchecked] unchecked generic array creation for varargs parameter of type Traversal<?,Vertex>[]
g.V().has("code","XYZ").fold().coalesce(unfold(),addV("airport").property("code","XYZ")).toList();
^
One last note, the coalesce
example in your question does not include a terminal step. Note the use of toList
in my example above. Without a terminal step, the query will not be executed against the server - hence nothing getting created.
Answered By - Kelvin Lawrence
Answer Checked By - Katrina (JavaFixing Volunteer)