Search code examples
python-3.xamazon-web-servicesgremlinamazon-neptunegremlinpython

Gremlin Python(AWS Neptune) get vertices with relations to list of other vertices


New to Gremlin_python and GraphDBs in general, we are using AWS neptune. I am trying to get a list of scenarios that have relations to a set of different tags e.g. give me all scenarios that has tag A and tag B. But the set of tags can be dynamic(from 1 to 10 elements).

The question as i understand it in GraphDB therms is:

Give me all vertices that has an outgoing edge with the label=tag to vertices with label A AND B. Picture of the Graph

For a none dynamic approach i get it to work with this guery:

e = g.V().and_(__.out('tag').hasLabel('A'), __.out('tag').hasLabel('B')).label().toList()

But i am not able to get this to work with a list of tags. I also did try this but it just generate an OR statement and i have not found a way to get it to do and:

label_list = ['A','B']
e = g.V().where(__.out('has tag').hasLabel((*label_list))).label().toList()

I also tried this approach with just getting the message "Connection was closed by server", i have seen this many times with AWS Neptune that instead of generating an error message a get connection closed instead anyone know way this happens?:

label_list = ['A','B']
e = g.V().and_(map(lambda x:__.out('has tag').hasLabel(x), label_list)).label().toList()
print(len(e))

We are testing this in the sage maker notebook using python 3.8.

So internet can you please generate an answer for me here?

BR Jon

List of includes in the notebook:

import yaml
from pathlib import Path
import json
import os

#from __future__  import print_function  # Python 2/3 compatibility

from gremlin_python import statics
from gremlin_python.structure.graph import Graph
from gremlin_python.process.graph_traversal import __
from gremlin_python.process.strategies import *
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.traversal import T
from gremlin_python.process.traversal import Order
from gremlin_python.process.traversal import Cardinality
from gremlin_python.process.traversal import Column
from gremlin_python.process.traversal import Direction
from gremlin_python.process.traversal import Operator
from gremlin_python.process.traversal import P
from gremlin_python.process.traversal import TextP
from gremlin_python.process.traversal import Pop
from gremlin_python.process.traversal import Scope
from gremlin_python.process.traversal import Barrier
from gremlin_python.process.traversal import Bindings
from gremlin_python.process.traversal import WithOptions

from argparse import ArgumentParser
from loguru import logger
import nest_asyncio
nest_asyncio.apply()

Solution

  • I did find one solution for the problem. More in a Python kind of way, than Gremlin. To flatten a list of code worked, but maybe there is a more readable solution.

    label_list = ['A','B']
    e = g.V().and_(*[__.out('tag').hasLabel(x) for x in label_list]).label().toList()
    

    A net trick i did figure out here is that you can send a list of tuples to the code. So you can dynamically add ANDs for both the out() and hasLabel().

    label_list = [('tag','A'),('tag','B'),('app','C')]
    e = g.V().and_(*[__.out(x[0]).hasLabel(x[1]) for x in label_list]).label().toList()