No value returned when using identity() in the within step, but values are returned when hardcoded

Viewed 106

I'm new to gremlin. Here's a sample graph

<?xml version='1.0' ?>
<graphml xmlns='http://graphml.graphdrawing.org/xmlns'>
    <key id='labelV'  for='node' attr.name='labelV'  attr.type='string'></key>
    <key id='type'    for='node' attr.name='type'    attr.type='string'></key>
    <key id='pick'    for='node' attr.name='pick'    attr.type='string'></key>
    <key id='match'   for='node' attr.name='match'   attr.type='string'></key>
    <key id='pot'  for='node' attr.name='pot'  attr.type='double'></key>
    <key id='stake'   for='node' attr.name='stake'   attr.type='double'></key>
    <key id='labelE'  for='edge' attr.name='labelE'  attr.type='string'></key>

<graph id='routes' edgedefault='directed'>
    <!-- vertices -->
    <node id='1'>
        <data key='labelV'>transaction</data>
        <data key='type'>transaction</data>
        <data key='match'>M1</data>
        <data key='pos'>H1</data>
        <data key='pick'>M1H1</data>
        <data key='pot'>100.0</data>
        <data key='stake'>10.0</data>
    </node>
    <node id='2'>
        <data key='labelV'>transaction</data>
        <data key='type'>transaction</data>
        <data key='match'>M1</data>
        <data key='pos'>D1</data>
        <data key='pick'>M1D1</data>
        <data key='pot'>50.0</data>
        <data key='stake'>5.0</data>
    </node>
    <node id='3'>
        <data key='labelV'>transaction</data>
        <data key='type'>transaction</data>
        <data key='match'>M1</data>
        <data key='pos'>A1</data>
        <data key='pick'>M1A1</data>
        <data key='pot'>150.0</data>
        <data key='stake'>15.0</data>
    </node>
    <node id='4'>
        <data key='labelV'>transaction</data>
        <data key='type'>transaction</data>
        <data key='match'>M2</data>
        <data key='pos'>A2</data>
        <data key='pick'>M2A2</data>
        <data key='pot'>75.0</data>
        <data key='stake'>10.0</data>
    </node>
    <node id='5'>
        <data key='labelV'>transaction</data>
        <data key='type'>transaction</data>
        <data key='match'>M3</data>
        <data key='pos'>A3</data>
        <data key='pick'>M3A3</data>
        <data key='pot'>70.0</data>
        <data key='stake'>7.0</data>
    </node>
    <node id='6'>
        <data key='labelV'>transaction</data>
        <data key='type'>transaction</data>
        <data key='match'>M1</data>
        <data key='pos'>H1</data>
        <data key='pick'>M1H1:M2D2</data>
        <data key='pot'>60.0</data>
        <data key='stake'>6.0</data>
    </node>

    <!-- edges -->
    <edge id='20' source='1' target='4'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='21' source='1' target='5'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='22' source='1' target='6'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='23' source='2' target='4'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='24' source='2' target='5'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='25' source='3' target='4'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='26' source='3' target='5'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='27' source='4' target='1'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='28' source='4' target='2'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='29' source='4' target='3'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='30' source='4' target='5'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='31' source='5' target='1'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='32' source='5' target='2'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='33' source='5' target='3'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='34' source='5' target='4'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='35' source='5' target='6'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='36' source='6' target='1'>
        <data key='labelE'>compatible</data>
    </edge>
    <edge id='37' source='6' target='5'>
        <data key='labelE'>compatible</data>
    </edge>
</graph>
</graphml>

I can't figure out how to add a property with with multiple values with graphML, so here's the code to add an additional value to V(6)

g.V(6).property(set, 'match', "M2")

The goal is to calculate the maximum pot in the graph by getting each node and its connected vertices, grouping the vertices of that node, by their match values ( grouping two nodes means they have at least one intersecting match value), taking the maximum of each group, and doing the sum for that node. At the end, with take the maximum value of all the nodes. I don't know if this is quite how it should be done but this is what I've tried:

g.E().hasLabel('compatible').outV().dedup().as('s').   //1. get all edges with comptible label
local(                                                 //2. for each node
    union(                                             //3. get the node and its first level connected vertices
        identity(),
        out()
    )
    .as('compat')
    .values('match')                                  //4. get the values of the match property

    .as('match')
    .local(                                           //5. for each key in the list
        select('compat')                              //6. get all vertices in the sub graph that have this value in their match list
        .has('match',within(identity()))              //7
        .order().by("pot", decr).limit(1)             //8. get the one with the highest pot value

    )
    .dedup()                                          //9. remove duplicates
    .values('pot')
    .sum()                                            //10. sum the values for this node
).max()                                               //11. get the max for all nodes

EXPECTED RESULT: For each vertex, we should have its BulkSet as follows:

V(5)==>[M1:[v[2],v[3],v[6],v[1]],M2:[v[4],v[6]],M3:[v[5]]]
V(6)==>[M1:[v[6],v[1]],M3:[v[5]]]
V(1)==>[M1:[v[1],v[6]],M2:[v[4], v[6]],M3:[v[5]]]
V(2)==>[M1:[v[2]],M2:[v[4]],M3:[v[5]]]
V(3)==>[M1:[v[3]],M2:[v[4]],M3:[v[5]]]
V(4)==>[M1:[v[1],v[2],v[3]],M2:[v[4]],M3:[v[5]]]

and the map of the maximum pots of each vertex:

V(5) ==> [M1:v[3],M2:v[4],M3:v[5]],     Sum(pot) ==> 150 + 75 + 70 = 295
V(6) ==> [M1:v[1],M3:v[5]],             Sum(pot) ==> 100 + 70      = 170
V(1) ==> [M1:v[1],M2:[v[4]],M3:v[5]],   Sum(pot) ==> 100 + 75 + 70 = 295
V(2) ==> [M1:v[2],M2:v[4],M3:v[5]],     Sum(pot) ==> 50  + 75 + 70 = 195
V(3) ==> [M1:v[3],M2:v[4],M3:v[5]],     Sum(pot) ==> 150 + 75 + 70 = 295
V(4) ==> [M1:v[3],M2:v[4],M3:v[5]],     Sum(pot) ==> 150 + 75 + 70 = 295

The final output should be 295.

The first problem is at 7. If I pass static values such as ['M1', 'M2'] I do get data but get an empty list with identity().

The second problem is at 8. I get multiple nodes instead of just the node with the maximum value.

2 Answers

I assume that your expected result is not quite right (M2 should be part of v[6]'s bulkset). That said, here's what I think the solution looks like:

gremlin> g.V().hasLabel("transaction").
           map(union(identity(), out("compatible")).as("v").
           values("match").
           group().
             by().
             by(select("v").order().by("pot", decr)))
==>[M1:v[1],M2:v[4],M3:v[5]]
==>[M1:v[2],M2:v[4],M3:v[5]]
==>[M1:v[3],M2:v[4],M3:v[5]]
==>[M1:v[3],M2:v[4],M3:v[5]]
==>[M1:v[3],M2:v[4],M3:v[5]]
==>[M1:v[1],M2:v[6],M3:v[5]]

gremlin> g.V().hasLabel("transaction").
           map(union(identity(), out("compatible")).as("v").
           values("match").
           group().
             by().
             by(select("v").order().by("pot", decr))).
           map(select(values).unfold().values("pot").fold())
==>[100.0,75.0,70.0]
==>[50.0,75.0,70.0]
==>[150.0,75.0,70.0]
==>[150.0,75.0,70.0]
==>[150.0,75.0,70.0]
==>[100.0,60.0,70.0]

gremlin> g.V().hasLabel("transaction").
           map(union(identity(), out("compatible")).as("v").
           values("match").
           group().
             by().
             by(select("v").order().by("pot", decr))).
           map(select(values).unfold().values("pot").sum()).
           max()
==>295.0

Worked for me on the example above:

g.V().hasLabel('transaction').local(
union(identity(), out('compatible')).as('v')
    .values('match')
    .group()
    .by()
    .by(select('v').values('pot').max()).select(values).unfold().sum()
).max()
Related