find path between vertices using edge properties in OrientDB - traversal

Is there a way to find a path between 2 vertices only including edges having a property with specific value in orient DB ?
I am able to find the path between 2 vertices but not able to filter out based on edge properties.

If you want the paths between 2 vertices, then you can do:
SELECT $path as path
FROM (
TRAVERSE outE(), inV() FROM #13:1
)
WHERE #rid == '14:2'
This basically goes through the out edges from #13:1, building the path. It will keep only those that end with the rid #14:2. One thing to note is that, it will return several paths, but if 2 two paths share a common track then only one of those will be retrieved (thats a thing with traverse command that for preventing loops and efficiency does that)
If you have further conditions you want to apply to the traversal, you can put them in the WHILE. Say you want to also take into consideration the value of test attribute from 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'
Here you need this 2 conditions because you are traversing both vertices and edges, so if its an edge you want to check on test attribute, if its a vertex, no condition, keep traversing.
NOTE:
There's a caveat from Traverse command where you cannot get all the possible paths between 2 vertices (excluding the paths with cicles), because traverse avoids traversing a node more than once, so the $path will only have one path containing the target vertex. Since we were filtering paths checking for the id of the traversed node, we only get one path be cause it doesnt traverse a node more than once. We need a way to find the paths without relying on traversed nodes....
we've got edges! Here is the 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 traverse from the source every path, but we filter those that includes the incomming edges from our target. If a path starting from the source includes an incomming edge from the target, its definitely a valid path between both.
Then we do a little trick to include the target vertex in the path so we can return a nice and complete path string.
This will return all paths between the 2 vertices, including the rels. It may be pretty greedy but is the only way i found to get all possible paths.

Don't know, if you're still looking for an answer, but you could try smth like this:
select from (traverse * from #13:1 while #rid <> #14:2) where test = 3
where #13:1 is an id for A, #14:2 - for E.

Related

Scala : how to keep only paths containing a full list of points

I have a problem where I need to find all the paths that contains a list of stops, both the list of paths and the list of points given in parameter.
A path is a Vector of segment, a segment is two points ("From" point and "To" point).
So far, my function to find a list of path which include a list of given points is
def containsListOfStops(paths: List[Path], points: List[Point]): List[Path]={
if (paths.isEmpty) List()
(for {
point <- points
path <- containsIntermediateStop(paths,point)
} yield path).distinct
containsIntermediateStop if a function which return a path containing a given point.
my problem is that it returns all the paths containing at least one of the points in the list, where I only want the paths containing every point.
Do you have any idea which could help me. Thanks.
you are sending each all paths and a single point to the containsIntermediateStop function.
How about doing something like
def containsPoints(path: Path, points: List[Point]): Boolean = ??? //implement checking all points in path
than you can simply do something like (no need for the for loop)
paths.distinct.filter(path => containsPoints(path, points))
is that works for you ?

select only vertex from TRAVERSE outE(), inV() FROM ... command

I have a SQL Command that currently works just fine as below
select from (traverse outE(), inV() from (select from Foo where name='root') while active=true) where #class='Foo'
However I think it will not work for the case I have many different types of vertex connected together. Therefore I need to replace the where condition with something like
select from (traverse outE(), inV() from (select from Foo where name='root') while active=true) where #elementType='Vertex'
Is there special function to determine element type which is available in Java API (OrientElement.getElementType())?
use this as where condition:
where #this instanceof 'V'

The provided start does not map to a value

I have a traversal as follows:
g.V().hasLabel("demoUser")
.as("demoUser","socialProfile","followCount","requestCount")
.select("demoUser","socialProfile","followCount","postCount")
.by(__.valueMap())
.by(__.out("socialProfileOf").valueMap())
.by(__.in("followRequest").hasId(currentUserId).count())
.by(__.outE("postAuthorOf").count())
I'm trying to select a user vertex, their linked social profile vertex, and some other counts. The issue is that all users may not have a socialProfile edge. When this is the case the traversal fails with the following error:
The provided start does not map to a value: v[8280]->[TitanVertexStep(OUT,[socialProfileOf],vertex), PropertyMapStep(value)]
I did find this thread from the gremlin team. I tried wrapping the logic inside of .by() with a coalesce(), and also appending a .fold() to the end of the statement with no luck.
How do I make that selection optional? I want to select a socialProfile if one exists, but always select the demoUser.
coalesce is the right choice. Let's assume that persons in the modern graph have either one or no project associated with them:
gremlin> g.V().hasLabel("person").as("user","project").
select("user","project").by("name").by(coalesce(out("created").values("name"),
constant("N/A")))
==>{user=marko, project=lop}
==>{user=vadas, project=N/A}
==>{user=josh, project=ripple}
==>{user=peter, project=lop}
Another way would be to completely exclude it from the result:
g.V().hasLabel("person").as("user","project").choose(out("created"),
select("user","project").by("name").by(out("created").values("name")),
select("user").by("name"))
But obviously this will only look good if each branch returns a map / selects more than 1 thing, otherwise you're going to have mixed result types.

Matlab structure with Children that are arrays of structs, etc. - How do trace path to all children individually?

I have a Matlab structure, A, that has 3 fields. The first field is SignalName and the third field is Children. Children can either be empty or a Struct array with the same fields, and so on, to an arbitrary depth not immediately known to the user. SignalName is a character array which is the name of a signal.
I have written a recursive function (in Matlab) to retrieve all of the SignalName values for structures that have no Children, and it's pretty slick (I think), but I need to know the absolute path taken to arrive at said SignalName. I cannot figure this out in Matlab.
As an example:
A.SignalName = 'Things'
A.Children = <22x1 struct>
A.Children(1).SignalName = 'Places'
A.Children(1).Children = [8x1 struct]
This goes on for an unknown depth, and the length of the struct arrays is not immediately known. It is easy via recursion to 'dive' down and get all of the SignalNames belonging to Children with no further Children, but how do I trace the route I used to get there? My function would ideally return results as a signal name, and the path taken to said signal.
In my experience with other languages, it seems like something like A* or Breadth-First might help, but I'm not exactly searching for something. I want simply to map every node and the path to it, and I'm not sure how to do that with the strange data-structure I'm given.
Thanks for any help you all can provide!
EDIT: I wanted to provide the code to hopefully shed light on my issue. I can get the paths down to the deepest node, but any other nodes at that level leave me without a complete path to that specific location. This is what I need help with. I am using '*' as my delimiter for a regexp in my post-processing script to break up the strings in PATHS.
For two nodes at the same depth, I might get a full path like 'A.B.C.D.Signal1' for the first node, but the second would give me a path of 'D.Signal2', when what I need is 'A.B.C.D.Signal2'. If the path was the same to the 'D' level with every signal, I would just copy the path over, but I have multiple branches in this struct from each level, and I go 4 or 5 levels deep.
function [NAMES,PATHS]=FindSignals(A,TMP,TMP2)
persistent SigName;
persistent path;
SigName = TMP;
path = TMP2;
if(~isempty(A.Children)) % If this struct has Children
for i = 1:length(A.Children) % Iterate through the Children
nextStruct = A.Children(i);
path = strcat([path '*' A.SignalName]);
[NAMES,PATHS] = FindSignals(nextStruct,SigName,path); % Recurse
end
else % If this struct has no Children
path = strcat([path '*' A.SignalName '*']); % Finish the path to Child
SigName = char(SigName,A.SignalName); % Grab the signal name
NAMES = SigName;
PATHS = path;
end
end
Again, thanks for any help!
EDIT: 12/14/2015 - I'm still completely stuck on this. Could anyone please take a peek at my source code above? I am unsure how to tack on an absolute path to the recursive function call and allow it to be a full path for each node at the same depth, and then reset to the appropriate depth once I move up or down the 'tree'. Thanks.

InstantiationException when using traversedElement

I'm attempting to setup a Graph which allows a query to follow "Redirect" edges from one vertex to another.
Vertices can only have a single Redirect edge going out; however, there may be a chain of Redirects that occur before reaching the final destination.
I'm attempting to grab the final vertex using the traversedElement function; however, even when I strip my implementation down to a query as simple as
select traversedElement(-1) from (traverse out() from #15:2)
I'm receiving the following error:
java.lang.InstantiationException: com.orientechnologies.orient.core.sql.functions.coll.OSQLFunctionTraversedElement
I'm not sure what the best way to debug this one might be, the simplified query I'm attempting above appears to match the documentation faithfully (documentation example):
SELECT traversedElement(-1) FROM ( TRAVERSE out() from #34:3232 WHILE $depth <= 10 )
Any words of wisdom would be greatly appreciated, thanks!
There was an issue with traversedElement() on last release (fixed on 2.0.7-SNAPSHOT). However you can use traversedEdge() and traversedVertex() that works.