图解Janusgraph系列-官方测试图:诸神之图(Graph of the gods)分析

大家好,我是洋仔,JanusGraph图解系列文章,实时更新~

图数据库文章总目录:

源码分析相关可查看github(码文不易,求个star~)https://github.com/YYDreamer/janusgraph

下述流程高清大图地址:https://www.processon.com/view/link/5f471b2e7d9c086b9903b629

版本:JanusGraph-0.5.2

转载文章请保留以下声明:

作者:洋仔聊编程
微信公众号:匠心Java
原文地址:https://liyangyang.blog.csdn.net/

诸神之图

Janusgraph中提供了一个用于测试的图,美名其曰“诸神之图”!英文名:Graph of the gods; 响当当的名字哈哈~~

如下图:

图解Janusgraph系列-官方测试图:诸神之图(Graph of the gods)分析

图中,对应的类型解释如下:

符号类型 含义
粗体key 图索引键
加粗 加星号的key 图唯一索引键
下划线key 顶点为中心的索引键,vertex-centric index
空心箭头edge 不可重复边,两个节点之间最多只能有一个该类型边
实心箭头edge 单向边,只能A–>B,不可以B–>A

包含类型

主要包含6种节点类型:

  • location:位置(sky:天空,sea:海,tartarus:塔耳塔洛斯)
  • titan:巨人(saturn:罗马神话中的农神)
  • god:神(jupiter,neptune,pluto)
  • demigod:半神(hercules)
  • human:人类(alcmene)
  • monster:怪物(nemean,hydra,cerberus)

主要包含6中边类型:

  • father:父亲
  • mother:母亲
  • brother:兄弟
  • battled:战斗
  • lives:生活在
  • pet:宠物

源码分析

源码在GraphOfTheGodsFactory类的下述方法中:

public static void load(final JanusGraph graph, String mixedIndexName, boolean uniqueNameCompositeIndex) {}

我们接下来分析一下,创建语句源码,具体分析一下图中的组成:

详细解释,已经在代码中注释

1、获取图管理对象实例

        if (graph instanceof StandardJanusGraph) {
            Preconditions.checkState(mixedIndexNullOrExists((StandardJanusGraph)graph, mixedIndexName), 
                    ERR_NO_INDEXING_BACKEND, mixedIndexName);
        }

        // Create Schema
        JanusGraphManagement management = graph.openManagement();

2、创建属性和对应索引

        // ===创建name属性; String、唯一CompositeIndex、锁机制保证name的强一致性
        final PropertyKey name = management.makePropertyKey("name").dataType(String.class).make();
        JanusGraphManagement.IndexBuilder nameIndexBuilder = management.buildIndex("name", Vertex.class).addKey(name);
        if (uniqueNameCompositeIndex)
            nameIndexBuilder.unique();
        JanusGraphIndex nameIndex = nameIndexBuilder.buildCompositeIndex();
        // 此处的LOCK,在name索引上添加了LOCK标识,标识这在并发修改相同的name属性时,必须通过锁机制(本地锁+分布式锁)保证并发修改;
        management.setConsistency(nameIndex, ConsistencyModifier.LOCK);

        // ===创建age属性;Integer、mixed index
        final PropertyKey age = management.makePropertyKey("age").dataType(Integer.class).make();
        if (null != mixedIndexName)
            management.buildIndex("vertices", Vertex.class).addKey(age).buildMixedIndex(mixedIndexName);

        // ===创建time属性
        final PropertyKey time = management.makePropertyKey("time").dataType(Integer.class).make();
        // ===创建reason属性
        final PropertyKey reason = management.makePropertyKey("reason").dataType(String.class).make();
        // ===创建place属性
        final PropertyKey place = management.makePropertyKey("place").dataType(Geoshape.class).make();
        // 为reason 和 place属性创建mixed index索引edges
        if (null != mixedIndexName)
            management.buildIndex("edges", Edge.class).addKey(reason).addKey(place).buildMixedIndex(mixedIndexName);

3、创建edge类型和对应索引

        // 创建边类型:father, many to one
        management.makeEdgeLabel("father").multiplicity(Multiplicity.MANY2ONE).make();
        // 创建边类型:mother, many to one
        management.makeEdgeLabel("mother").multiplicity(Multiplicity.MANY2ONE).make();
        // 创建边类型:battled, 签名密匙为time:争斗次数,
        EdgeLabel battled = management.makeEdgeLabel("battled").signature(time).make();
        // 为battled边创建一个以顶点为中心的 中心索引(vertex-centric index),索引属性time; 双向索引,可以从 神->怪物 也可以 怪物->神
        // 将查询节点对应的 battled 边时,可以使用这个vertex-centric索引,索引属性为 time;
        // vertex-centric index为了解决大节点问题,一个节点存在过多的边!
        management.buildEdgeIndex(battled, "battlesByTime", Direction.BOTH, Order.desc, time);
        // 创建边类型:lives,签名密匙为reason
        management.makeEdgeLabel("lives").signature(reason).make();
        // 创建边类型:pet
        management.makeEdgeLabel("pet").make();
        // 创建边类型:brother
        management.makeEdgeLabel("brother").make();

4、创建vertex类型

        // 创建节点label
        management.makeVertexLabel("titan").make();
        management.makeVertexLabel("location").make();
        management.makeVertexLabel("god").make();
        management.makeVertexLabel("demigod").make();
        management.makeVertexLabel("human").make();
        management.makeVertexLabel("monster").make();

5、提交创建的schema数据

 management.commit();

6、插入数据

获取图事务对象:

JanusGraphTransaction tx = graph.newTransaction();

插入节点数据:

        // 插入节点
        Vertex saturn = tx.addVertex(T.label, "titan", "name", "saturn", "age", 10000);
        Vertex sky = tx.addVertex(T.label, "location", "name", "sky");
        Vertex sea = tx.addVertex(T.label, "location", "name", "sea");
        Vertex jupiter = tx.addVertex(T.label, "god", "name", "jupiter", "age", 5000);
        Vertex neptune = tx.addVertex(T.label, "god", "name", "neptune", "age", 4500);
        Vertex hercules = tx.addVertex(T.label, "demigod", "name", "hercules", "age", 30);
        Vertex alcmene = tx.addVertex(T.label, "human", "name", "alcmene", "age", 45);
        Vertex pluto = tx.addVertex(T.label, "god", "name", "pluto", "age", 4000);
        Vertex nemean = tx.addVertex(T.label, "monster", "name", "nemean");
        Vertex hydra = tx.addVertex(T.label, "monster", "name", "hydra");
        Vertex cerberus = tx.addVertex(T.label, "monster", "name", "cerberus");
        Vertex tartarus = tx.addVertex(T.label, "location", "name", "tartarus");

插入边数据:

        // 插入边数据
        jupiter.addEdge("father", saturn);
        jupiter.addEdge("lives", sky, "reason", "loves fresh breezes");
        jupiter.addEdge("brother", neptune);
        jupiter.addEdge("brother", pluto);

        neptune.addEdge("lives", sea).property("reason", "loves waves");
        neptune.addEdge("brother", jupiter);
        neptune.addEdge("brother", pluto);

        hercules.addEdge("father", jupiter);
        hercules.addEdge("mother", alcmene);
        hercules.addEdge("battled", nemean, "time", 1, "place", Geoshape.point(38.1f, 23.7f));
        hercules.addEdge("battled", hydra, "time", 2, "place", Geoshape.point(37.7f, 23.9f));
        hercules.addEdge("battled", cerberus, "time", 12, "place", Geoshape.point(39f, 22f));

        pluto.addEdge("brother", jupiter);
        pluto.addEdge("brother", neptune);
        pluto.addEdge("lives", tartarus, "reason", "no fear of death");
        pluto.addEdge("pet", cerberus);

        cerberus.addEdge("lives", tartarus);

提交事务,持久化数据:

        // 提交事务,持久化提交的数据到磁盘
        tx.commit();

码字不易,求个赞和star~

上一篇:Linux 的make及makefile文件格式


下一篇:CPU性能测试工具coremark使用