I have a Question about the shortestPath() Function of OrientDB. If I Query select shortestPath('#9:1', '#15:1', 'BOTH')
against a OrientDB I just get the Vertex of the Path. But I also want the Edges between them.
How can I SELECT both, the Vertex and the Edges?

- 334
- 3
- 14
3 Answers
You can use a javascript function.
I used these records
I used this code
var g=orient.getGraph();
var b=g.command("sql","select expand(shortestPath(" + start + "," + end + ", 'BOTH'))");
var list=[];
for(i=0;i<b.length-1;i++){
var rid1=b[i].getId();
var rid2=b[i+1].getId();
var query="select from e where out = " + rid1 + " and in = " + rid2 + " limit 1";
var edge=g.command("sql",query);
list.push(b[i]);
list.push(edge[0]);
if(i==b.length-2){
list.push(b[i+1]);
}
}
return list;
Hope it helps.

- 3,560
- 1
- 8
- 10
-
Thank you, this will work for sure. Maybe it's not the best solution for the problem because with a long path this will take some time. I will use your solution anyways and maybe someone have a better one. – Marvin K Apr 26 '16 at 08:04
-
After testing it I get the error: "java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0" – Marvin K Apr 26 '16 at 10:57
-
The Select Query for the Edge should be `select from e where (out = "#15:3" and in = "#15:1") or (in = "#15:3" and out = "#15:1") limit 1` – Marvin K Apr 26 '16 at 11:13
I tried this Java code with Alessandro's structure:
import java.util.ArrayList;
import java.util.List;
import com.orientechnologies.orient.client.remote.OServerAdmin;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
public class myClass {
private boolean stop=false;
private List<Vertex> visitedNodesPreviousStep=new ArrayList<Vertex>();
private List<Vertex> visitedNodeCurrently=new ArrayList<Vertex>();
private List<List<Vertex>> path_vertex=new ArrayList<List<Vertex>>();
private List<List<Edge>> path_edges=new ArrayList<List<Edge>>();
private OrientGraph g;
int step=0;
public myClass(OrientGraph g) {
this.g=g;
}
protected List<Object> getDistance(String starting_rid, String ending_rid) {
Vertex starting_node=g.getVertex(starting_rid);
Vertex ending_node=g.getVertex(ending_rid);
visitedNodesPreviousStep.add(starting_node);
List<Vertex> p1=new ArrayList<Vertex>();
p1.add(starting_node);
path_vertex.add(p1);
step=1;
boolean found_node_to_be_added=false;
do{
stop=false;
found_node_to_be_added=false;
for(Vertex v: visitedNodesPreviousStep){
List<Edge> edges_to_be_added=new ArrayList<Edge>();
List<Vertex> nodes_to_be_added=new ArrayList<Vertex>();
Iterable<Edge> it_edge = (Iterable<Edge>) v.getEdges(Direction.OUT);
for(Edge e1:it_edge){
Vertex v1=e1.getVertex(Direction.IN);
edges_to_be_added.add(e1);
nodes_to_be_added.add(v1);
String rid=v1.getId().toString();
if(!rid.equals(ending_rid)){ // checking the current @rid isn't the ending
visitedNodeCurrently.add(v1);
}
else{ // ending node found
setPathFoundList(v,ending_node,step,e1);
stop=true;
}
}
if(nodes_to_be_added.size()!=0 && stop==false){
found_node_to_be_added=true;
setpath_vertex(v,nodes_to_be_added,edges_to_be_added);
}
}
if(found_node_to_be_added==false){
stop=true;
}
System.out.println("step = " + step + " " +path_vertex);
change();
step++;
}while(stop==false);
clean_vertex_path(ending_node);
return getShortestPathList();
}
public void change(){
visitedNodesPreviousStep.clear();
for(Vertex v:visitedNodeCurrently)
visitedNodesPreviousStep.add(v);
visitedNodeCurrently.clear();
}
private void setPathFoundList(Vertex node,Vertex ending_node,int step,Edge edge){
for(int i=0;i<path_vertex.size();i++){
List<Vertex> path=path_vertex.get(i);
Vertex last=path.get(path.size()-1);
if(last.getId().equals(node.getId()) && path.size()==step){
path.add(ending_node);
List<Edge> edgesPath=path_edges.get(i);
edgesPath.add(edge);
}
}
}
private void setpath_vertex(Vertex node,List<Vertex> nodes_to_be_added,List<Edge> edges_to_be_added) {
for(int i=0;i<path_vertex.size();i++){
List<Vertex> path=path_vertex.get(i);
Vertex last=path.get(path.size()-1);
if(last.getId().equals(node.getId())){
int j=0;
for(int h=0;h<nodes_to_be_added.size();h++){
boolean name_present=false;
for(Vertex p:path){
if(p.getId().equals(nodes_to_be_added.get(h).getId()))
name_present=true;
}
if(name_present==false){
List<Vertex> p2=new ArrayList<Vertex>();
for(Vertex p:path)
p2.add(p);
p2.add(nodes_to_be_added.get(h));
List<Edge> e2=new ArrayList<Edge>();
if(step==1){
e2.add(edges_to_be_added.get(h));
}
else{
List<Edge> edgesPath=path_edges.get(i);
for(Edge p1:edgesPath)
e2.add(p1);
e2.add(edges_to_be_added.get(h));
}
if(j==0){
path_vertex.set(i, p2);
if(step==1){
path_edges.add(i, e2);
}
else{
path_edges.set(i, e2);
}
j++;
}
else{
path_vertex.add(p2);
path_edges.add(e2);
}
}
}
}
}
}
public void clean_vertex_path(Vertex ending_node_name){
for(int i=0;i<path_vertex.size();i++){
List<Vertex> path=path_vertex.get(i);
if(!path.get(path.size()-1).getId().equals(ending_node_name.getId())){
path_vertex.remove(i);
path_edges.remove(i);
i--;
}
}
}
public List<Object> getShortestPathList(){
List<Object> result=new ArrayList<Object>();
if(path_vertex.size()==0)
return new ArrayList<Object>();
else{
List<Vertex> path=path_vertex.get(0);
int min_size= path.size();
for(int i=0;i<path_vertex.size();i++){
if(path_vertex.get(i).size()<=min_size){
List<Vertex> path2= path_vertex.get(i);
List<Edge> edges2= path_edges.get(i);
for(int k=0;k<path2.size();k++){
result.add(path2.get(k));
if(k!=path2.size()-1)
result.add(edges2.get(k));
}
}
}
}
return result;
}
public static void main(String[] args) {
String remote="remote:localhost/";
String DBname="Stack36794694";
String currentPath=remote+DBname;
OServerAdmin serverAdmin;
try {
serverAdmin = new OServerAdmin(currentPath).connect("root", "root");
if(serverAdmin.existsDatabase()){
OrientGraph g=new OrientGraph(currentPath);
myClass shortest2 = new myClass(g);
System.out.println("SHORTEST PATH " + shortest2.getDistance("#9:0","#9:5"));
}
}
catch(Exception e){
}
}
}
Hope it helps

- 1,418
- 9
- 12
Its been a long time since the question was asked. As of OrientDB version 3.2.6, the following query retrieves the vertices and edges on the shortest path in order
SELECT FROM (TRAVERSE * FROM #51:0 WHILE
(@this INSTANCEOF V AND @rid IN (SELECT shortestPath(#51:0, #60:40).asList())) OR
(@this INSTANCEOF E AND (@this.in IN (SELECT shortestPath(#51:0, #60:40).asList()))) );
Where (example database) #51:0 is the start vertex, #60:40 is the end vertex and the shortest path is found between them.
The idea was to find the shortest path with the function and then traverse from the start node, visiting all the nodes in the shortest path and all the edges whose 'in' vertex is in the shortest path.
NOTE: I have used a graph which did not have multiple edges between vertices. However, by extension the above can be made to work in that situation as well.
If there are unrelated edges incident on any one of the vertices which is on the shortest path, the '@this.out' check can be included to filter them.

- 3,402
- 4
- 25
- 32