Gremlin: how to find other edges with the same property - gremlin

I have a graph with two vertices having id(s) 'a' and 'b'.
gremlin> g.V()
==>v[b]
==>v[a]
There are two edges from 'a' to 'b'.
gremlin> g.E()
==>e[a6b4bead-c161-5a61-d232-abfa2bfad54e][a-LIKES->b]
==>e[10b4bead-a0fc-8d2c-d69f-26b3e9e4c5d8][a-KNOWS->b]
gremlin> g.E().valueMap(true)
==>{id=a6b4bead-c161-5a61-d232-abfa2bfad54e, semantics=social, label=LIKES}
==>{id=10b4bead-a0fc-8d2c-d69f-26b3e9e4c5d8, semantics=social, label=KNOWS}
My question: given an id for one of the edges, I would like to find all other edges with the same value for the property "semantics". For example, given a.LIKES.id, I would like to execute a query that will return a.KNOWS using the value a.LIKES.semantics.
I started with:
g.E('a6b4bead-c161-5a61-d232-abfa2bfad54e')
.property('semantics').as('semantics')...this is where I am stuck
Thanks,
Joel

where() in conjunction with a by() modulator will do the job:
g.E('a6b4bead-c161-5a61-d232-abfa2bfad54e').as('e').
outV().inE().
where(eq('e')).by('semantics'). // return edges with the same semantics property value
where(neq('e')) // ... except the one we started with

Related

Searching members of primitive data array assigned at a property in Janusgraph

In Janusgraph, We can assign primitive type array into property of Vertex or Edge.
Sample code.
gremlin> arr = new int[2]
gremlin> arr[0] = 0
gremlin> arr[1] = 1
gremlin> g.E(1).property("prop1", arr)
Finding the property which has equal array members
gremlin> arr2 = new int[2]
gremlin> arr2[0] = 0
gremlin> arr2[1] = 1
gremlin> g.E().has("prop1", arr)
But how can I find them with member? (in this case, 0 or 1)
Thank you.
I didn't think you could search within arrays with JanusGraph with Gremlin directly as a property value. You'd have to match on the entire array value as you demonstrated. If you wanted to search the values independently of each other (0 or 1 as in your question) you would need to use multi-properties. Here is an example from a similar question with JanusGraph.
g.E().filter(values("prop1").unfold().is(0))
This query works. but I can't sure its performance is good enough.
Thank you

CosmosDB Gremlin - filter nodes that don't have a particular type of edge

In a CosmosDB Graph collection, I'm trying to find all nodes of type typeA that do not have any "live" edges pointing to nodes of type typeB.
Some edges may be "soft-deleted" (i.e. g.E().has('softDeleted', true) ). These edges should be ignored.
This is what I tried:
g.V().hasLabel('typeA')
-> returns 10 nodes of type "typeA", as expected
g.V().hasLabel('typeA')
.outE().not(has('softDelete', true))
.inV().hasLabel('typeB')
-> returns 2 nodes of type "typeB", as expected
g.V().hasLabel('typeA')
.where( // same condition as above, inside a 'where' clause
outE().not(has('softDelete', true))
.inV().hasLabel('typeB')
.count().is(eq(0)) // " where there are no such edges"
)
-> returns all 10 nodes of type "typeA" again ?!
In the query above, applying the where clause seems to not filter anything.
The following query will find all typeA vertices that do not have an edge to a typeB vertex. Only edges that have no softDelete property or that edges that have softDelete set to false will be considered, other edges will be ignored.
g.V().hasLabel('typeA').
not(outE().or(hasNot('softDelete'),
has ('softDelete', false)).
inV().hasLabel('typeB'))

Gremlin: is it possible to filter on optional properties? (graph database is Neptune)

I have a graph with a single vertex:
gremlin> g.V().valueMap(true)
==>{id=a, x=[foo], label=vertex}
The vertex can be found in the following query:
gremlin> g.V().has('x', 'foo')
==>v[a]
However, I would like to modify the above query with the additional match constraint: match the vertex if it does not have property "y", or if the vertex does have property "y" and the value for property "y" equals "bar".
I have constructed the following query.
g.V().has('x', 'foo').or(__.hasNot('y'), __.has('y', 'bar'))
The query returns no matching vertices. So, I think I am looking for something equivalent to "IFNULL()" in mysql.
Any advice is much appreciated!
Joel
There's nothing wrong with your or() filter, it should just work.
gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV().property(id, 'a').property('x', 'foo').iterate()
gremlin> g.V().has('x', 'foo').or(__.hasNot('y'), __.has('y', 'bar'))
==>v[a]
Alternatively you can check that there's no y value that is not bar.
gremlin> g.V().has('x', 'foo').not(__.values('y').is(neq('bar')))
==>v[a]
However, double negations tend to be confusing, so I would just go with or().

In Gremlin, how can one query vertices where one property value is greater than another property value?

I'm sure this is straightforward, but I'm not sure how to do it. I have vertices, with a certain label, which have two integer properties. Let's call them integer1 and integer2. I simply want to query for all vertices where integer2 is greater than integer1.
I have tried the following:
g.V().hasLabel("myLabel").has("integer2", P.gt(values("integer1"))).toList();
but this results in an exception - understandably, as the the "values" method call results in a traversal step where as the predicate expects a number.
Exception in thread "main" java.lang.ClassCastException: org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal cannot be cast to java.lang.Integer
at java.lang.Integer.compareTo(Integer.java:52)
at org.apache.tinkerpop.gremlin.process.traversal.Compare$3.test(Compare.java:92)
at org.apache.tinkerpop.gremlin.process.traversal.P.test(P.java:72)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer.testValue(HasContainer.java:118)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer.test(HasContainer.java:94)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer.testAll(HasContainer.java:180)
at org.apache.tinkerpop.gremlin.tinkergraph.process.traversal.step.sideEffect.TinkerGraphStep.iteratorList(TinkerGraphStep.java:116)
at org.apache.tinkerpop.gremlin.tinkergraph.process.traversal.step.sideEffect.TinkerGraphStep.vertices(TinkerGraphStep.java:88)
at org.apache.tinkerpop.gremlin.tinkergraph.process.traversal.step.sideEffect.TinkerGraphStep.lambda$new$0(TinkerGraphStep.java:59)
at org.apache.tinkerpop.gremlin.tinkergraph.process.traversal.step.sideEffect.TinkerGraphStep$$Lambda$23/1123629720.get(Unknown Source)
...
Any help would be greatly appreciated. Thanks.
One way to do it would be with a where() clause. First, to demonstrate I modified the "modern" graph to include a "k" property with an integer value:
g = TinkerFactory.createModern().traversal()
g.V().hasLabel('person').property('k',30)
and then:
gremlin> g.V().hasLabel('person').as('a').
......1> where('a', gt('a')).by('age').by('k').
......2> valueMap('age','k')
==>[k:[30],age:[32]]
==>[k:[30],age:[35]]

Return subset of properties from a node through Gremlin query

Is there a way to return just a subset of all properties of a graph node with a Gremlin query?
I know you cand use the transform pipe to concatenate property values, but I'm more interested in obtaining structured results (like propertyName1 = value1, propertyName2 = value2).
Assuming you're using Gremlin-Groovy, I find using Groovy's each construct to be a useful way to create my own objects from Gremlin query results. For example:
nodes = []
g.V.each{ node ->
nodes += [ propertyName1 : node.value1, propertyName2 : node.value2 ]
}
Now you have a List of Map objects representing nodes returned from your query. It's possible this isn't the most efficient way but it is very flexible.
As of Gremlin 2.4.0, you can do:
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1).out.map('name')
==>{name=vadas}
==>{name=josh}
==>{name=lop}
gremlin> g.v(1).out.map('name','age')
==>{age=27, name=vadas}
==>{age=32, name=josh}
==>{age=null, name=lop}
It is possible doing this:
If data is:
gremlin> g.E.has('weight', T.gt, 0.5f).outV.age
==>32
==>29
Then the query to do is:
gremlin> g.E.has('weight', T.gt, 0.5f).outV.transform{[id:it.id,age:it.age]}
==>{id=4, age=32}
==>{id=1, age=29}
Have you looked at using Table??
Sample from : Gremlin Wiki
gremlin> t = new Table()
gremlin> g.v(1).out('knows').as('x').out('created').as('y').table(t){it.name}{it.name}
==>v[5]
==>v[3]
gremlin> t
==>[x:josh, y:ripple]
==>[x:josh, y:lop]

Resources