gremlin_python连接图数据库的使用及增删查改方法封装

Posted by Jack on 2019-09-16
Words 2.1k and Reading Time 10 Minutes
Viewed Times

一、安装Janusgraph图数据库

1、下载离线安装包

前往janusgraph的官方发布页下载离线安装包,如下图所示,目前最新的版本是0.4.0,点击janusgraph-0.4.0-hadoop2.zip下载即可。请注意,该安装包只能在linux系统下安装!!!

2、解压运行

打开终端,使用unzip命令解压下载好的zip安装包,然后进入到janusgraph-0.4.0目录下,执行 bin/janusgraph.sh start ,会得到如下的运行结果,说明janusgraph运行成功。

1
2
3
4
5
6
7
8
$ bin/janusgraph.sh start
Forking Cassandra...
Running `nodetool statusthrift`.. OK (returned exit status 0 and printed string "running").
Forking Elasticsearch...
Connecting to Elasticsearch (127.0.0.1:9300)... OK (connected to 127.0.0.1:9300).
Forking Gremlin-Server...
Connecting to Gremlin-Server (127.0.0.1:8182)... OK (connected to 127.0.0.1:8182).
Run gremlin.sh to connect.

3、其他操作

janusgraph-0.4.0目录下,执行 bin/janusgraph.sh status ,可以查看janusgraph的运行状态及进程ID,而执行 bin/janusgraph.sh stop ,则关闭janusgraph及其相关的所有进程。

1
2
3
4
5
6
7
8
9
$ ./bin/janusgraph.sh status
Gremlin-Server (org.apache.tinkerpop.gremlin.server.GremlinServer) is running with pid 31841
Elasticsearch (org.elasticsearch.bootstrap.Elasticsearch) is running with pid 31668
Cassandra (org.apache.cassandra.service.CassandraDaemon) is running with pid 31336

$ bin/janusgraph.sh stop
Killing Gremlin-Server (pid 31841)...
Killing Elasticsearch (pid 31668)...
Killing Cassandra (pid 31336)...

二、通过Gremlin连接Janusgraph图数据库

1、使用gremlin控制台连接

janusgraph-0.4.0目录下,执行 bin/gremlin.sh 则可启动gremlin控制台,如下所示。然后可以进行gremlin的相关操作,如:remote命令告诉控制台使用conf/remote.yaml配置文件与gremlin服务进行远程连接,:>是“提交”命令,比如 :> graph.addVertex("name", "test")是添加了一个name为test的节点,然后 :> g.V().values('name')则是查询该图中所有节点中含有name属性的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$  bin/gremlin.sh
\,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.hadoop
plugin activated: tinkerpop.utilities
plugin activated: janusgraph.imports
plugin activated: tinkerpop.tinkergraph
gremlin> :remote connect tinkerpop.server conf/remote.yaml
==>Connected - localhost/127.0.0.1:8182
gremlin> :> graph.addVertex("name", "test")
==>v[4726]
gremlin> :> g.V().values('name')
==>test

2、使用gremlin_python连接

首先需要安装gremlin_python这个依赖包,使用pip命令安装 pip install gremlinpython==3.4.1 ,这里要注意的是 janusgraph0.4.0支持的gremlin最高版本为3.4.1,所以安装的时候需指定版本号。
安装完成后,便可在python程序中进行连接了,注意此时需要保证janusgraph处于运行状态。

1
2
3
4
5
6
7
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.anonymous_traversal import traversal

connection = DriverRemoteConnection('ws://127.0.0.1:8182/gremlin', 'g')
graph = traversal().withRemote(connection)
graph.addV('person').property('name', 'test').next() # 添加节点
print(graph.V().values('name').toList()) # 输出为 ['test']

三、对图数据库进行增删查改的方法封装

1、添加节点到图数据库中

只需传入新增节点的 label 以及 properties(dict,可选),返回 Vertex(id, label)类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
def add_vertex(graph, label, properties=None):
"""
add vertex
:param graph: graph, type: GraphTraversalSource
:param label: label, type: str
:param properties: property dict, like {'p1': 'value1', 'p2': 'value2'}
:return: vertex, Vertex(id, label)
"""
vert = graph.addV(label)
if properties:
for key in properties.keys():
vert.property(key, properties.get(key))
return vert.next()

2、添加边到图数据库中

传入新增边的 labelproperties(dict,可选),以及需要添加边的两节点(或其ID)v_fromv_to

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def add_edge(graph, label, v_from, v_to, properties=None):
"""
add edge
:param graph: graph, type: GraphTraversalSource
:param label: label, type: str
:param v_from: long vertex id or Vertex(id, label) of from
:param v_to: long vertex id or Vertex(id, label) of to
:param properties: property dict, like {'p1': 'value1', 'p2': 'value2'}
:return: None
"""
if isinstance(v_from, int):
v_from = graph.V().hasId(v_from).next()
if isinstance(v_to, int):
v_to = graph.V().hasId(v_to).next()
edge = graph.V(v_from).addE(label).to(v_to)
if properties:
for key in properties.keys():
edge.property(key, properties.get(key))
edge.next()

3、删除图数据库中的节点

可以根据要求来删除特定节点,如根据节点(或其ID)、label、properties。如果不传入其他参数,则默认删除所有节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def drop_vertex(graph, v_id=None, label=None, properties=None):
"""
drop all vertex or specific vertex
:param graph: graph, type: GraphTraversalSource
:param v_id: long vertex id or Vertex(id, label)
:param label: label, type: str
:param properties: property list, like ['p1', 'p2', {'p3': 'value'}]
:return: None
"""
if isinstance(v_id, int):
v_id = graph.V().hasId(v_id).next()
travel = graph.V(v_id) if v_id else graph.V()
if label:
travel = travel.hasLabel(label)
if properties:
for p in properties:
if isinstance(p, dict):
key = list(p.keys())[0]
travel = travel.has(key, p.get(key))
else:
travel = travel.has(p)
travel.drop().iterate()

4、删除图数据库中的边

可以根据要求来删除特定边,如根据边ID、label、properties。如果不传入其他参数,则默认删除所有边

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def drop_edge(graph, e_id=None, label=None, properties=None):
"""
drop all edges or specific edge
:param graph: graph, type: GraphTraversalSource
:param e_id: edge id, type str
:param label: label, type: str
:param properties: property list, like ['p1', 'p2', {'p3': 'value'}]
:return: None
"""
travel = graph.E(e_id) if e_id else graph.E()
if label:
travel = travel.hasLabel(label)
if properties:
for p in properties:
if isinstance(p, dict):
key = list(p.keys())[0]
travel = travel.has(key, p.get(key))
else:
travel = travel.has(p)
travel.drop().iterate()

5、查询图数据库中的节点

首先,可以根据节点(或其ID)查询该节点的所有属性值,此时需使用return travel.valueMap().toList()
其次,可以通过 label 或 properties 来查询符合条件的所有节点,此时使用return travel.toList()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def query_vertex(graph, v_id=None, label=None, properties=None):
"""
query graph vertex (value) list
:param graph: graph, type: GraphTraversalSource
:param v_id: long vertex id or Vertex(id, label)
:param label: label, type: str
:param properties: property list, like ['p1', 'p2', {'p3': 'value'}]
:return: vertex list or vertex value list
"""
if isinstance(v_id, int):
v_id = graph.V().hasId(v_id).next()
travel = graph.V(v_id) if v_id else graph.V()
if label:
travel = travel.hasLabel(label)
if properties:
for p in properties:
if isinstance(p, dict):
key = list(p.keys())[0]
travel = travel.has(key, p.get(key))
else:
travel = travel.has(p)
# return travel.valueMap().toList()
return travel.toList()

6、查询图数据库中的边

根据边的ID、label 或 properties 来查询符合条件的边的所有属性值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def query_edge(graph, e_id=None, label=None, properties=None):
"""
query graph edge value list
:param graph: graph, type: GraphTraversalSource
:param e_id: edge id, type str
:param label: label, type: str
:param properties: property list, like ['p1', 'p2', {'p3': 'value'}]
:return: valueMap list
"""
travel = graph.E(e_id) if e_id else graph.E()
if label:
travel = travel.hasLabel(label)
if properties:
for p in properties:
if isinstance(p, dict):
key = list(p.keys())[0]
travel = travel.has(key, p.get(key))
else:
travel = travel.has(p)
return travel.valueMap().toList()

7、查询所有与某个节点相连的边

根据节点(或其ID)查询与该节点相连的所有边

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def query_edges_of_vertex(graph, v_id):
"""
query all edges of vertex
:param graph: graph, type: GraphTraversalSource
:param v_id: v_id: long vertex id or Vertex(id, label)
:return: edge list
"""
if isinstance(v_id, int):
v_id = graph.V().hasId(v_id).next()
result = []
in_edges = graph.V(v_id).inE().toList()
out_edges = graph.V(v_id).outE().toList()
result.extend(in_edges)
result.extend(out_edges)
return result

8、查询所有与某个节点相连的节点

根据节点(或其ID)查询与该节点相连的所有节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def query_near_vertex(graph, v_id):
"""
query near vertices of vertex
:param graph: graph, type: GraphTraversalSource
:param v_id: v_id: long vertex id or Vertex(id, label)
:return: vertex list
"""
if isinstance(v_id, int):
v_id = graph.V().hasId(v_id).next()
result = []
out_v = graph.V(v_id).out().toList()
in_v = graph.V(v_id).in_().toList()
result.extend(out_v)
result.extend(in_v)
return result

四、其他常用方法封装

1、获取边的ID

1
2
3
4
5
6
7
def get_edge_id(edge):
"""
get edge id
:param edge: Egde(id, label, outV, inV)
:return: edge id, type str
"""
return edge.id.get('@value').get('relationId')

2、节点属性转字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def vertex_to_dict(graph, vertex):
"""
transfer Vertex's info to dict
:param graph: graph, type: GraphTraversalSource
:param vertex: vertex, Vertex(id, label)
:return: vertex info dict
"""
properties = graph.V(vertex).valueMap().toList()[0]
for key in properties.keys():
properties[key] = properties.get(key)[0]
return {
'id': vertex.id,
'label': vertex.label,
'properties': properties
}

3、边属性转字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def edge_to_dict(graph, edge):
"""
transfer Edge's info to dict
:param graph: graph, type: GraphTraversalSource
:param edge: edge, Edge(id, label, outV, inV)
:return: edge info dict
"""
e_id = get_edge_id(edge)
properties = graph.E(e_id).valueMap().toList()[0]
return {
'id': e_id,
'label': edge.label,
'properties': properties
}

4、判断节点是否在图数据库中

对于已知节点的 label 和 properties 值,判断该节点是否在图中;如果在,返回该节点,否则返回None。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def judge_vertex_in_graph(graph, vertex_dict):
"""
judge a vertex whether in graph
:param graph: graph, type: GraphTraversalSource
:param vertex_dict: vertex dict, like {'label': 'value1', 'properties': {'p1': 'v1', ...}}
:return: None or Vertex(id,label)
"""
label = vertex_dict.get('label')
properties = vertex_dict.get('properties')
travel = graph.V()
if label:
travel = travel.hasLabel(label)
if properties:
for k in properties.keys():
travel = travel.has(k, properties.get(k))
if travel.hasNext():
return travel.next()
return None

5、获取某个子图

根据特定的节点信息或者边信息来获取子图。

1
2
3
4
5
6
7
8
9
10
11
def get_sub_graph(graph, vertices=None, edges=None, vertex_properties=None):
"""
get sub graph
:param graph: graph, type: GraphTraversalSource
:param vertices: hasLabel('label').has('property').has('age', gt(20))
:param edges: hasLabel('label').has('property')
:param vertex_properties:
:return: sub_graph, type: GraphTraversalSource
"""
strategy = SubgraphStrategy(vertices=vertices, edges=edges, vertex_properties=vertex_properties)
return graph.withStrategies(strategy)

五、致谢

以上所有代码都供参考学习,非常感谢大家的阅读。如果有任何问题,都可通过Email与我联系,希望大家一起学习,共同进步。


...

...

00:00
00:00