大家好,我是洋仔
,JanusGraph图解系列文章,实时更新
~
图数据库文章总目录:
- 整理所有图相关文章,请移步(超链):图数据库系列-文章总目录
- 地址:https://liyangyang.blog.csdn.net/article/details/111031257
源码分析相关可查看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
; 响当当的名字哈哈~~
图
如下图:
图中,对应的类型解释如下:
符号类型 | 含义 |
---|---|
粗体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~