一、安装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
7from 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
13def 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、添加边到图数据库中
传入新增边的 label 和 properties(dict,可选),以及需要添加边的两节点(或其ID)v_from和v_to。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19def 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
22def 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
20def 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
23def 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
20def 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
15def 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
15def 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  | def get_edge_id(edge):  | 
2、节点属性转字典
1  | def vertex_to_dict(graph, vertex):  | 
3、边属性转字典
1  | def edge_to_dict(graph, edge):  | 
4、判断节点是否在图数据库中
对于已知节点的 label 和 properties 值,判断该节点是否在图中;如果在,返回该节点,否则返回None。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18def 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
11def 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与我联系,希望大家一起学习,共同进步。

...
...