Needing a little help to filter edges based on its propriety

556 views
Skip to first unread message

Ulrik

unread,
May 15, 2012, 8:15:55 PM5/15/12
to Gremlin-users
Hi, it's the whole day that I'm reading and trying with gremlin, and
I've almost done what I'm looking for... I just need a last step which
I cannot figure it out.

Here's my problem: I've a weight value on the edges, it can be
positive or negative, I look from a vertex down to a deep level equal
to 3, but it's followed only if the weight value of the middle edges
is not present or is not negative (it's ok if it's negative and it's
the last edge). As return I'd like a list of the last edge's weight,
or maybe better a sum of all them (when there are more paths).

This is what I've achieved until now (from vertex A to B):
g.v(A).as('x').outE.inV.loop('x'){it.loops < 3}{it.object.id ==
B}.simplePath.paths{it.weight}
this gives me: [null, -0.5, null]

the problem is that it also gives me (to a different B vertex): [null,
-0.5, null, null, null]
which is not correct, as the first edge is -0.5 it should not continue

So: [null, 0.1, null], [null, null, null], [null, -0.2, null], [null,
null, null, null, 0.3, null], [null, null, null, null, null, null],
[null, null, null, null, -0.4, null], they're all correct

[null, -0.1, null, null, ANYTHING, null] should be ignored

Considering this, it should return only the last weight, so [null,
0.1, null, null, -0.2, null] => -0.2
Or maybe even better a sum of the last weights for all the paths
returned: ([null, 0.1, null, -0.2, null], [null, 0.3, null], [null,
0.1, null, 0.1, null]) => 0.2

Do you have any idea what should I change in order to get this
behavior?

Marko Rodriguez

unread,
Jul 23, 2012, 10:07:14 AM7/23/12
to gremli...@googlegroups.com
Hi,

Your problem doesn't require gather(). You can do it like this:

a = []; b = []
v(100).in.outE.sideEffect{it.weight == 10 ? a << it : b << it}.iterate()

a will have all edges with weight 10.
b will have all edge with weight not-10.

Using the toy TinkerPop graph, here is your solution:

gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1)
==>v[1]
gremlin> g.v(1).outE
==>e[7][1-knows->2]
==>e[8][1-knows->4]
==>e[9][1-created->3]
gremlin> g.v(1).outE.weight
==>0.5
==>1.0
==>0.4
gremlin> a = []; b = []    
gremlin> g.v(1).outE.sideEffect{it.weight == 1.0 ? a << it : b << it}   
==>e[7][1-knows->2]
==>e[8][1-knows->4]
==>e[9][1-created->3]
gremlin> a
==>e[8][1-knows->4]
gremlin> b
==>e[7][1-knows->2]
==>e[9][1-created->3]
gremlin> a.weight
==>1.0
gremlin> b.weight
==>0.5
==>0.4

Finally, for optimum performance, note that it.weight is not efficient because it uses Java reflection. it.getProperty('weight') is fastest. See:
For just "REPL"ing around, it.weight is nice and handy.

Enjoy,
Marko.


On Jul 23, 2012, at 4:42 AM, Akanksha wrote:

i have one problem which is similar to yours.
get all the edges and filter them on the basis of property weight

v(100).in.outE._().gather{ if(it.weight == 10) a = it; else b = it;}

i want to store all outgoing edges either in a or in b.
but if condition is not working properly here .
can anybody help me to achieve what i want.
Thanks in advance.


Nikhil

unread,
Jul 23, 2012, 10:27:06 AM7/23/12
to gremli...@googlegroups.com
@Marko, Akanksha:

Could we use aggregate() step in this case?

Here's something from my Gremlin shell:

gremlin> a=[];b=[];g.v(1).outE.has('weight', T.gte, new Float("0.5")).aggregate(a).back(3).outE.hasNot('weight', T.gte, new Float("0.5")).aggregate(b)
==>e[9][1-created->3]
gremlin> a
==>e[7][1-knows->2]
==>e[8][1-knows->4]
gremlin> b
==>e[9][1-created->3]
gremlin> a.weight
==>0.5
==>1.0
gremlin> b.weight
==>0.4
gremlin> 

I realized that I'm traversing over the same set of edges twice. Tried to make it better with an ifThenElse step:

gremlin> a=[];b=[];g.v(1).outE.ifThenElse{it.getProperty('weight') >= 0.5}{a << it}{b << it}                                                          
==>e[7][1-knows->2]
==>e[7][1-knows->2]
==>e[8][1-knows->4]
==>e[9][1-created->3]
gremlin> a
==>e[7][1-knows->2]
==>e[8][1-knows->4]
gremlin> b
==>e[9][1-created->3]
gremlin> a.weight
==>0.5
==>1.0
gremlin> b.weight
==>0.4
gremlin> 

What do you guys think?

--
Nikhil Lanjewar
Engineering Lead at YourNextLeap

Marko Rodriguez

unread,
Jul 23, 2012, 10:32:57 AM7/23/12
to gremli...@googlegroups.com
Hi,

Your ifThenElse() works. Basically, ifThenElse() step is analogous to a sideEffect{} step with if/then/else in it.

Your first expression is just plain crazy :).

See ya,
Marko.

Nikhil

unread,
Jul 23, 2012, 10:37:56 AM7/23/12
to gremli...@googlegroups.com
> Your first expression is just plain crazy :).
Oh yes, I realized the craziness the moment I looked at it again! :)
Reply all
Reply to author
Forward
0 new messages