Search code examples
graphgremlintinkerpop3datastax-enterprise-graphgremlinpython

Gremlin Python project By clause


Have a graph running on Datastax Enterprise Graph (5.1 Version), running on Cassandra storage. Trying to run a query to get both the ID and the property. In Gremlin Console I can do this:

gremlin> g.V(1).project("v", "properties").by().by(valueMap())
==>[v:v[1],properties:[name:[marko],age:[29]]]

How can I translate the valueMap call still using Python GraphTraversal API. I know I can run a direct query via Session Execution, like this.

session.execute_graph("g.V().has(\"Node_Name\",\"A\").project(\"v\", \"properties\").by().by(valueMap())",{"name":graph_name})

Below is my setup code.

from dse.cluster import Cluster, EXEC_PROFILE_GRAPH_DEFAULT
from dse_graph import DseGraph
from dse.cluster import GraphExecutionProfile, EXEC_PROFILE_GRAPH_SYSTEM_DEFAULT
from dse.graph import GraphOptions
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 Pop
from gremlin_python.process.traversal import Scope
from gremlin_python.process.traversal import Barrier
graph_name = "TEST"
graph_ip = ["127.0.0.1"]
graph_port = 9042
schema = """
schema.edgeLabel("Group").create();
schema.propertyKey("Version").Text().create();
schema.edgeLabel("Group").properties("Version").add()
schema.vertexLabel("Example").create();
schema.edgeLabel("Group").connection("Example", "Example").add()
schema.propertyKey("Node_Name").Text().create();
schema.vertexLabel("Example").properties("Node_Name").add()
schema.vertexLabel("Example").index("exampleByName").secondary().by("Node_Name").add();
"""
profile = GraphExecutionProfile(
    graph_options=GraphOptions(graph_name=graph_name))
client = Cluster(
    contact_points=graph_ip, port=graph_port,
    execution_profiles={EXEC_PROFILE_GRAPH_DEFAULT: profile}
)
graph_name = graph_name
session = client.connect()
graph = DseGraph.traversal_source(session)

# force the schema to be clean
session.execute_graph(
    "system.graph(name).ifExists().drop();",
    {'name': graph_name},
    execution_profile=EXEC_PROFILE_GRAPH_SYSTEM_DEFAULT
)
session.execute_graph(
    "system.graph(name).ifNotExists().create();",
    {'name': graph_name},
    execution_profile=EXEC_PROFILE_GRAPH_SYSTEM_DEFAULT
)
session.execute_graph(schema)
session.shutdown()
session = client.connect()
graph = DseGraph.traversal_source(session)

Update:

I guess i have not made the problem clear. It is in python and not in gremlin console. So running code like graph.V().has("Node_Name","A").project("v","properties").by().by(valueMap()).toList() will give following result. How to execute the gremlin query while still remain in the GLV level, not drop down to text serialized query to Gremlin-Server?

Traceback (most recent call last):
  File "graph_test.py", line 79, in <module>
    graph.V().has("Node_Name","A").project("v", "properties").by().by(valueMap()).toList()
NameError: name 'valueMap' is not defined

Solution

  • I may not fully understand your question but it seems like you largely have the answer most of the way there. This last line of code:

    graph = DseGraph.traversal_source(session)
    

    should probably be written as:

    g = DseGraph.traversal_source(session)
    

    The return value of traversal_source(session) is a TraversalSource and not a Graph instance and by convention TinkerPop tends to refer to such a variable as g. Once you have a TraversalSource, then you can just write your Gremlin.

    g = DseGraph.traversal_source(session)
    g.V().has("Node_Name","A").project("v", "properties").by().by(valueMap()).toList()