Last active
March 15, 2022 11:50
-
-
Save joshwolff1/b61748f9342a4a3ef597d3d3b72ef027 to your computer and use it in GitHub Desktop.
Some abstractions for the gremlin-python module.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from gremlin_python.structure.graph import Graph | |
from gremlin_python.process.graph_traversal import __ | |
# I use a property instead of directly setting the ID because I could not get it to work, and this works | |
# just as well for now. I'd imagine setting the id directly is better for runtime. | |
# If you figure out how to set the id directly with gremlin-python, feel free to make a pull request and I'll merge it. | |
IDENTIFICATION_PROPERTY = 'identification' | |
WEIGHT_PROPERTY = 'weight' | |
""" | |
Feel free to use this for gremlin-python, which does not have a lot of clear documentation on the differences between | |
itself and Groovy, even though there are many. | |
This gist offers some abstracted functions to make starting with gremlin-python easy. | |
To connect to AWS Neptune with gremlin, you have to use a VPC - you can ssh in your console for example, | |
but cannot run a script from PyCharm. | |
See how to connect to AWS Neptune from AWS Lambda, which reduces running database operations to basically running a | |
PyCharm script, for testing. | |
https://docs.aws.amazon.com/neptune/latest/userguide/get-started-cfn-lambda.html | |
""" | |
def remove_vertex_from_graph(v, g): | |
""" | |
remove_node_from_graph | |
:param v: the vertex to remove | |
:param g: the graph | |
:return: - | |
""" | |
g.V(v).drop().iterate() | |
def add_vertex_to_graph(ident, label, g): | |
""" | |
add_node_to_graph | |
:param ident: the id for the new vertex | |
:param label: the label classifying the vertex | |
:param g: the graph | |
:return: - | |
""" | |
return g.addV(label).property(IDENTIFICATION_PROPERTY, str(ident)).next() | |
def remove_edge_from_graph(edge, g): | |
""" | |
remove_node_from_graph | |
:param edge: the edge to remove | |
:param g: the graph | |
:return: - | |
""" | |
g.E(edge).drop().iterate() | |
def add_edge_to_graph(v1, v2, label, g): | |
""" | |
connect_edges | |
:param v1: vertex 1 | |
:param v2: vertex 2 | |
:param relation: a string label for the edge | |
:param g: the graph | |
:return: - | |
""" | |
return g.V(v1).addE(label).to(g.V(v2)).next() | |
def update_edge_weight(edge, increment, g): | |
""" | |
update_edge_weight | |
:param edge: the edge to increment | |
:param increment: the amount by which to increment the weight | |
:return: - | |
""" | |
g.E(edge).property(WEIGHT_PROPERTY, increment + get_edge_weight(edge, g).next()) | |
def get_edge_weight(edge, g): | |
""" | |
get_edge_weight | |
:param edge: the edge, of the type returned by get_edge | |
:return: the weight of the given edge | |
""" | |
values = g.E(edge).valueMap().next() | |
return values.get(WEIGHT_PROPERTY, 0) | |
def get_edge(v1_id, v2_id, label, g): | |
""" | |
get_edge | |
:param v1_id: the string id of the first vertex | |
:param v2_id: the string id of the second vertex | |
:param label: string label of the edge, such as 'knows' | |
:param g: the graph | |
:return: the edge | |
""" | |
try: | |
return g.V(v1_id).outE(label).where(__.inV().where(__.hasId(v2_id))).next() | |
except: | |
# The edge does not exist. | |
return None | |
def get_vertex(ident, label, g): | |
""" | |
get_vertex | |
:param ident: string id of the vertex | |
:param label: the label of the vertex | |
:param g: the graph | |
:return: the vertex | |
""" | |
try: | |
return g.V().hasLabel(label).has(IDENTIFICATION_PROPERTY, ident).next() | |
except: | |
# The vertex does not exist | |
return None | |
def get_vertices_going_out_from_vertex_with_edge_label(v, g, label=None): | |
""" | |
get_vertices_going_out_from_vertex_with_edge_label | |
:param v: the vertex | |
:param g: the graph | |
:param label: optional parameter - if defined, returns all vertices connected to the given vertex via an edge of the | |
defined label. If not defined, returns all vertices going out from the specified vertex | |
:return: a list of vertices | |
""" | |
if label is None: | |
# outE gets edges going out | |
return g.V(v).out().fold().next() | |
else: | |
return g.V(v).out(label).fold().next() | |
def get_vertices_going_in_to_vertex_with_edge_label(v, g, label=None): | |
""" | |
get_vertices_going_in_to_vertex_with_edge_label | |
:param v: the vertex | |
:param g: the graph | |
:param label: optional parameter - if defined, returns all vertices connected to the given vertex via an edge of the | |
defined label. If not defined, returns all vertices going out from the specified vertex | |
:return: a list of vertices | |
""" | |
if label is None: | |
# inE gets edges going in | |
return g.V(v).in_().fold().next() | |
else: | |
return g.V(v).in_(label).fold().next() | |
def get_label_counts(g): | |
""" | |
get_label_counts | |
:param g: the graph | |
:return: a dictionary mapping string labels to integer counts | |
""" | |
return g.V().label().groupCount().next() | |
def get_edges_with_label(label, g): | |
""" | |
get_edges_with_label | |
:param label: a string label | |
:return: a list of edges with the label considered | |
""" | |
return g.V().out(label).fold().next() | |
def get_vertices(g, label=None): | |
""" | |
get_vertices | |
:param g: the graph | |
:param label: optional parameter; the label type of the vertices considered | |
:return: a list of vertices | |
""" | |
if label is None: | |
return g.V().fold().next() | |
else: | |
return g.V(label).fold().next() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ah gotcha! I am not sure why that is the case, primarily because I don't know too much Gremlin, but I recommend joining this Google Group (see link below) and asking the question there. There are some real pros on there that can help you out.
https://groups.google.com/forum/#!forum/gremlin-users