Search code examples
gremlintinkerpopamazon-neptune

Gremlin/Tinkerpop - is there a way to add metadata to a union step so I know which query the resulting traversal came from?


This is a little strange, but I have a situation where it'd be beneficial for me to know which traversal an element came from.

For a simple example, something like this:

.union(
   select('parent').out('contains'),   //traversal 1
   select('parent2').out('contains')   //traversal 2
)
.dedup()
.project('id','traversal')
.by(id())
.by( //any way to determine which traversal it came from? or if it was in both? )

Edit: One thing I found is that I can use Map with Group/By to get partly there:

.union(
   select('parent').out('contains')
   .map(group().by(identity()).by(constant('t1'))),  
   select('parent2').out('contains')   
   .map(group().by(identity()).by(constant('t2'))), 
)
.dedup() //Dedup isn't gonna work here because each hashmap will be different.
.project('id','traversal')
.by( //here I can't figure out how to read a value from the hashmap inline )

The above query without the project/by piece returns this:

[{v[199272505353083909]: 't1'}, {v[199272515180338177]: 't2'}]

Or is there a better way to do this?

Thanks!


Solution

  • One simple approach might be to just fold the results. If you get back an empty list you will know you did not find any on that "branch":

    g.V('44').
      union(out('route').fold().as('a').project('res','branch').by().by(constant('b1')),
            out('none').fold().as('b').project('res','branch').by().by(constant('b2')))
    

    which yields

    {'res': [v[8], v[13], v[20], v[31]], 'branch': 'b1'}
    {'res': [], 'branch': 'b2'}
    

    UPDATED after discussion in comments to include an alternative approach that uses nested union steps to avoid the project step inside the union. I still think I prefer the project approach unless the performance when measured is not good.

    g.V('44').
      union(local(union(out('route').fold(),constant('b1')).fold()),
            local(union(out('none').fold(),constant('b2')).fold()))
    

    which yields

    [[v[8], v[13], v[20], v[31]], 'b1']
    [[], 'b2']