Gremlin query to give response for 1 and 2 hops at same time

I have a graph setup with certain type of vertices like: inputFiles, outputFiles, convertors convertors basically take some input files, process them and produce output files. For example: convertor-abc -----output----> outputFile-1 | | input | | inputFile-1 this inputFile-1 can be an input to more than one convertors., an input file can also be an output file for another convertor vice versa for output file. I need to write a gremlin query which takes an input file id, looks for all the convertors for which this input file is given as input, and also all the input output files given to these convertors and gives in response; For example: { "file": "inputFile-id", "convertors": [ { "convertor": "convertor-1", "inputs" : [ { "file": "inputFile-id-1" }, { "file": "inputFile-id-2" } ], "outputs" : [ { "file": "outputFile-id-1" }, { "file": "outputFile-id-2" } ] }, { "convertor": "convertor-2", "inputs" : [ { "file": "inputFile-id-3" }, { "file": "inputFile-id-4" } ], "outputs" : [ { "file": "outputFile-id-3" }, { "file": "outputFile-id-4" } ] } ] } How can I achieve this in single gremlin query, also it is fesable to have a single query to achieve this? or its better to break the query into two and first we fetch all the convertors and then look for its input output files?
6 Replies
spmallette
spmallette•16mo ago
When asking questions about Gremlin it's usually best to include some sample data to make things clear and so that we can provide a tested query as an answer. Your diagram and your explanation of your schema don't quite align for me. Is this representative of your data? if not, please edit and provide a more accurate example:
g.addV('inputFile').property('fid','if1').as('if1').
addV('inputFile').property('fid','if2').as('if2').
addV('inputFile').property('fid','if3').as('if3').
addV('inputFile').property('fid','if4').as('if4').
addV('outputFile').property('fid','of1').as('of1').
addV('outputFile').property('fid','of2').as('of2').
addV('outputFile').property('fid','of3').as('of3').
addV('outputFile').property('fid','of4').as('of4').
addV('converter').property('name','converter1').as('c1').
addV('converter').property('name','converter2').as('c2').
addE('input').from('if1').to('c1').
addE('input').from('if2').to('c2').
addE('input').from('if3').to('c1').
addE('input').from('if4').to('c1').
addE('output').from('c1').to('of1').
addE('output').from('c1').to('of3').
addE('output').from('c1').to('of4').
addE('output').from('c2').to('of2').
iterate()
g.addV('inputFile').property('fid','if1').as('if1').
addV('inputFile').property('fid','if2').as('if2').
addV('inputFile').property('fid','if3').as('if3').
addV('inputFile').property('fid','if4').as('if4').
addV('outputFile').property('fid','of1').as('of1').
addV('outputFile').property('fid','of2').as('of2').
addV('outputFile').property('fid','of3').as('of3').
addV('outputFile').property('fid','of4').as('of4').
addV('converter').property('name','converter1').as('c1').
addV('converter').property('name','converter2').as('c2').
addE('input').from('if1').to('c1').
addE('input').from('if2').to('c2').
addE('input').from('if3').to('c1').
addE('input').from('if4').to('c1').
addE('output').from('c1').to('of1').
addE('output').from('c1').to('of3').
addE('output').from('c1').to('of4').
addE('output').from('c2').to('of2').
iterate()
HailDevil
HailDevil•16mo ago
apologies @spmallette yes that is the correct representation of the graph. I just added one more correction, please check https://gremlify.com/gko236mppr6 thanks for your response
spmallette
spmallette•16mo ago
so, given:
g.addV('inputFile').property('fid','if1').as('if1').
addV('inputFile').property('fid','if2').as('if2').
addV('inputFile').property('fid','if3').as('if3').
addV('inputFile').property('fid','if4').as('if4').
addV('outputFile').property('fid','of1').as('of1').
addV('outputFile').property('fid','of2').as('of2').
addV('outputFile').property('fid','of3').as('of3').
addV('outputFile').property('fid','of4').as('of4').
addV('converter').property('name','converter1').as('c1').
addV('converter').property('name','converter2').as('c2').
addE('input').from('if1').to('c1').
addE('input').from('if2').to('c2').
addE('input').from('if3').to('c1').
addE('input').from('if4').to('c1').
addE('output').from('c1').to('of1').
addE('output').from('c1').to('of3').
addE('output').from('c1').to('of4').
addE('output').from('c2').to('of2').
addE('input').from('of3').to('c2').
iterate()
g.addV('inputFile').property('fid','if1').as('if1').
addV('inputFile').property('fid','if2').as('if2').
addV('inputFile').property('fid','if3').as('if3').
addV('inputFile').property('fid','if4').as('if4').
addV('outputFile').property('fid','of1').as('of1').
addV('outputFile').property('fid','of2').as('of2').
addV('outputFile').property('fid','of3').as('of3').
addV('outputFile').property('fid','of4').as('of4').
addV('converter').property('name','converter1').as('c1').
addV('converter').property('name','converter2').as('c2').
addE('input').from('if1').to('c1').
addE('input').from('if2').to('c2').
addE('input').from('if3').to('c1').
addE('input').from('if4').to('c1').
addE('output').from('c1').to('of1').
addE('output').from('c1').to('of3').
addE('output').from('c1').to('of4').
addE('output').from('c2').to('of2').
addE('input').from('of3').to('c2').
iterate()
i think you just need an nested project():
g.V().has('inputFile','fid','if1').as('s').
project('file','converters').
by('fid').
by(out('input').project('converter','inputs','outputs').
by('name').
by(__.in('input').values('fid').fold()).
by(__.out('output').values('fid').fold()))
g.V().has('inputFile','fid','if1').as('s').
project('file','converters').
by('fid').
by(out('input').project('converter','inputs','outputs').
by('name').
by(__.in('input').values('fid').fold()).
by(__.out('output').values('fid').fold()))
The output doesn' t quite match what you're asking but that should inspire you to the solution if you need to match it exactly:
gremlin> g.V().has('inputFile','fid','if1').as('s').
......1> project('file','converters').
......2> by('fid').
......3> by(out('input').project('converter','inputs','outputs').
......4> by('name').
......5> by(__.in('input').values('fid').fold()).
......6> by(__.out('output').values('fid').fold()))
==>[file:if1,converters:[converter:converter1,inputs:[if1,if3,if4],outputs:[of1,of3,of4]]]
gremlin> g.V().has('inputFile','fid','if1').as('s').
......1> project('file','converters').
......2> by('fid').
......3> by(out('input').project('converter','inputs','outputs').
......4> by('name').
......5> by(__.in('input').values('fid').fold()).
......6> by(__.out('output').values('fid').fold()))
==>[file:if1,converters:[converter:converter1,inputs:[if1,if3,if4],outputs:[of1,of3,of4]]]
HailDevil
HailDevil•16mo ago
@spmallette hey thanks!! I needed to get the list of converters for which a added .fold() which fulfilled my purpose. Appreciate your help 🙂 just one more query, do you believe the query can face issues due to loops?
spmallette
spmallette•16mo ago
i don't think so. you usually worry about loops when you have repeat() which if you don't use proper guards can lead to traversals that simply never end. but here you only traverse in()/out() a finite number of times, so unless you don't want such outputs i don't think there's a problem
HailDevil
HailDevil•16mo ago
got it!! thanks a lot
Want results from more Discord servers?
Add your server