How to check for a property in a vertex or its child using gremlin-cosmos - gremlin

I am traversing a path a,b,c,d in my graph where a,b,c,d are the nodes along the traversed path.
(a)->(b)->(c)->(d)
My traversal will end at node d as node d is a leaf node.
I want my traversal to cover all nodes from a to d and it must not come to a halt before it reaches node d.
The goal of the traversal is to find out if a certain property exists in node c or d. If for example the property does not exit in node c, I'd like to check if it does exist in its child node d first before the path is rendered invalid.
How do I achieve this with gremlin query on cosmos? Is there such a thing as an optional has() in Gremlin?
Nodes c and d are labeled differently however they have the same properties.
Currently, I have this query, but it would fail if node c didn't have the property of interest even though node d might have it.
G.V().hasLabel('a').out().as('b').out().as('c').has('status', 'patched').out().as('d').has('status', 'patched')
If either node c or node d have the property 'status': 'patched' is good enough and the path is valid (aka. I want that path in my result to the query)
I am doing this on CosmosDB, so please only provide answers using supported steps found here: https://learn.microsoft.com/en-us/azure/cosmos-db/gremlin/support

The goal of the traversal is to find out if a certain property exists in node c or d.
This sounds like an or() step:
G.V().hasLabel('a').out().out().or(
__.has('status', 'patched').out(),
__.out().has('status', 'patched')
).path()

Related

How to filter by property in Gremlin (if exist)?

I am new Gremlin and having trouble with filtering by property.
A -> B
Assume A and B are vertices and has edge between them with properties Created_on and deleted_on.
deleted_on property will be added only at the time of deletion.
How list by the edge property?
g.V(id).outE('Label').has('deleted_on', lt(timestamp.now())).outV().elementMap()
The above query returns empty, because the deleted_on property is not added to the edge yet.
How to handle this?
I'm not completely sure but I think you are looking to find all connections where the deleted_on property is less than now or it does not exist. If that is the case then you can use the or() and hasNot() steps in Gremlin to accomplish this similar to the query below.
g.V(id).
outE('Label').
has('deleted_on', lt(timestamp.now())).
or().
hasNot('deleted_on').
outV().
elementMap()

Gremlin query to traverse graph bottom to top capturing vertex children

We use Gremlin 3.2 compatible database. Actually, we try Cosmos DB in graph/gremlin mode. But I am looking to gremlin query so not necessary it is related only to Cosmos DB
The graph looks like on the image below
I have created a query that is able to capture red vertices/nodes.
g.V("A").emit().repeat(__.in('depends')).until(__.inE().count().is(0))
But struggling to extend a query to capture direct children of each vertex. On the image marked as blue ones.
Can anybody help with such a gremlin query?
Here is a query in online editor https://gremlify.com/spml2ktk03
If using the online editor:
Actual: B->A->D->TOP
Expected: B-> A (including info about C) -> D
(including info about E) -> TOP
You should be able to accomplish what you are looking for by using store() to store all the vertices in the tree and then for each iteration of the repeat you can use sideEffect() to find it's children and store them as well.
g.V().hasLabel('B').store('v').
repeat(__.in('depends').store('v').
sideEffect(out('depends').store('v'))).
until(__.inE().
count().is(0)).cap('v')
This returns me:
B -> A -> C- > D -> E -> TOP

How to get the list of all incoming intermediate vertices between a source vertex and target vertex of specific label using Gremlin query?

The Gremlin query that I use to get the list of all outgoing vertices (with edge label “has”) from a selected vertex “P1” until it reaches the vertex with specific label “L3” is this:
g.V().has("id”,”P1”).repeat(out(“has”)).until(hasLabel(“L3”)).path().by("id")
As expected, the query above returns me the list of all intermediate nodes between selected vertex and target vertex labeled “L3”.
However, when using the same query (changing the ‘out’ to ‘in’) in opposite direction, i.e., to get the list of all incoming vertices from a selected vertex to the target vertex with specific label, i get a gremlin query error straight away.
Here is the query:
g.V().has("id”,”P3”).repeat(in(“has”)).until(hasLabel(“L1”)).path().by("id")
The error looks like this:
Failure in submitting query:
Error: Script compile error: Missing ')'
I don’t see any missing brackets in the query though and the only change between the queries for incoming or outgoing vertices i made is using ‘in’ instead of ‘out’.
In the official tinkerpop documentation (https://tinkerpop.apache.org/docs/3.2.9/reference/#_traversal_strategies_2), in traversal strategies, I cannot find any example with repeat(in()), only with repeat(out()). Is there a special query or method to get all the incoming vertices from a selected vertex until it reaches the vertex with a specific label?
I'm not sure if this is your problem or not, but I could see where you would get an error because "in" is a reserved word in Groovy so, you have to explicitly spawn it using the anonymous traversal class with: __.in(), therefore:
g.V().has("id","P3").repeat(__.in("has")).until(hasLabel("L1")).path().by("id")
This issue is documented in a number of places in the Reference Documentation, but perhaps you missed it (you referenced a fairly old version of the documentation as well) - described here in a NOTE in the Vertex Steps for example.

How to exclude some paths in Neo4j Cypher

I have 2 sets of paths
Collection 1
A->B->C->D
A->E->F->D
A->G->J->H
I->B->C->D
Collection 2
E->D
I->D
The Cypher query output should be paths of Collection 1 where nodes combination of 2nd collection does not exist.
In above example, nodes E,D of Collection 2, 1st element exist in 2nd path of Collection 1, so the 2nd should be dropped. similarly, nodes I,D of collection 2, 2nd element exist in 4th path of Collection 1, so the 4th should also be dropped.
Then the output should be
Collection 3
A->B->C->D
A->G->J->H
Through Cypher, I'm able to find out paths of collection 1 in which nodes of collection 2 paths exist but I'm not able to do a 'minus' operation among collections.
How to get the cypher query to achieve above?
Thanks in advance
Rasyq
Without your Cypher queries it's not easy to answer. But in general you can get the nodes from a path with nodes(your_path) and check if all of those nodes are included in another path with the all() predicate.
MATCH p1 = (your first paths), p2 = (the paths you check against)
// filter paths where NOT all nodes of p2 are in p1
WHERE NOT all(node2 IN nodes(p2) WHERE node2 IN p1)
RETURN p1

Gremlin, join vertices of same type and add edge when the properties empNo and mgrno matches

I have vertices with properties like
vertex("empNo","age","Date","mgrNo")
a(101,20,'dd-mm-yy',0)
b(102,22,'dd-mm-yy',101)
Since mgrNo of b matches with empNo of a ie, a is the manager of b.
I have to add an edge between a and b.
Please tell me how to do this in gremlin .
I assume that you want to iterate all vertices. You could do it with a sideEffect pretty easily:
g.V.has("mgrNo",neq,0).sideEffect{
g.V.has("empNo",it.mgrNo).next().addEdge("manages",it)
}
Note that if you are using a graph that supports transactions you will need to commit() your changes to persist them.

Resources