Find path between vertices using edge properties in OrientDB

Is there a way to find a path between two vertices, including only edges that have a property with a specific value in a directed DB?

I can find the path between the two vertices, but I couldn't filter based on the edge properties.

+3


source to share


2 answers


If you need paths between two vertices, you can do:

SELECT $path as path
FROM (
    TRAVERSE outE(), inV() FROM #13:1
) 
WHERE @rid == '14:2'

      

It basically goes over the edge from # 13: 1 creating a path. It will only contain those that end with # 14: 2 . It should be noted that it will return multiple paths, but if two two paths share a common track, then only one of them will be retrieved (this is a move command thing that does this to prevent loops and efficiency)

If you have additional conditions that you want to apply to the crawl, you can put them in WHILE. Let's say you also want to consider the value of the test attribute along the edges:

SELECT $path as path
FROM (
    TRAVERSE outE(), inV() FROM #13:1
    WHILE (@class == 'V') OR (@class == 'E' AND test == 3)
) 
WHERE @rid == '14:2'

      

You need these 2 conditions here because you are moving both vertices and edges, so if it is an edge you want to check on the test attribute, if its vertex has no conditions, keep moving.



Note:

There's a caveat from the Traverse team where you cannot get all possible paths between two vertices (excluding paths with cicles), because the traverse avoids crossing a node more than once, so the $ path has only one path containing the target vertices. Since we were filtering the paths checking the id of the node traversed, we only get one path because it doesn't traverse the node more than once. We need a way to find paths without relying on the nodes passed ...

We have edges! Here's a workaround:

BEGIN;
LET target = SELECT @rid as rid, inE() as ins FROM <target_id>
LET paths = SELECT $path as path 
            FROM (TRAVERSE outE(), inV() FROM <source_id>) 
            WHERE @rid in $target['ins'];

if ($paths.size() > 0) {
    LET result = SELECT path.append(".inV(").append($target['rid'][0]).append(")") from $paths;
}

if ($paths.size() == 0) {
    LET result = SELECT FROM $paths;
}

COMMIT;
RETURN $result; 

      

So we're going from source to each path, but we're filtering out those that include incoming edges from our target. If the path starting at the source includes an adjacent edge from the target, this is definitely a valid path in between. Then we do a little trick to include the target vertex in the path so that we can return a nice and complete path string.

This will return all paths between the two vertices, including rels. It can be quite greedy, but it is the only way to find all possible paths.

+1


source


Don't know if you're still looking for an answer, but you can try something like this:

select from (traverse * from #13:1 while @rid <> #14:2) where test = 3

      



where #13:1

- id for A, # 14: 2 - for E.

0


source







All Articles