阅读 252

一网打尽JanusGraph"出边入边无向边双向边"

起因参考我之前创建图数据表的操作,要给“刘备”和“关羽”添加【兄弟】关系,要分别输入刘备有个兄弟叫关羽,关羽有个兄弟叫刘备,神烦!

问题

在网上搜查了半天愣是没找到怎么给jg图数据库的2个顶点添加一个双向的关系,无奈翻了下官网和源码,整理分享如下:

JanusGraph有双向边吗?

先说答案:"没有"。

需要双向边怎么办?

"如果需要双向边,则通过添加两条相反方向的单向边实现。"

建议使用时封装一个方法即可。

边的方向

看源码的org.janusgraph.graphdb.relations.EdgeDirection:

public class EdgeDirection {
    public static final Direction[] PROPER_DIRS = {Direction.IN, Direction.OUT};
    ……
}
复制代码

白纸黑字仅有INOUT两个方向。

JanusGraph不存在无向边。

无向边和双向边

一般来说,在图数据库中这两个概念的表达意图是一样的,也就是说“双向”和“无向”都是表示【关系】对两个顶点均适用。如“同学”关系,“同事”关系,“兄弟”关系,“掘友”关系等。你是我同学,我也是你同学。

但我爱你,你就不一定爱我,“爱”有方向:I --[love]--> you。

directed和unidirected

但是源码org.janusgraph.core.schema.EdgeLabelMaker接口中有两个方法:

  • directed()
  • unidirected()
/**
     * Configures the label to be directed.
     * By default, the label is directed.
     * @return this EdgeLabelMaker
     * @see org.janusgraph.core.EdgeLabel#isDirected()
     */
    EdgeLabelMaker directed();

    /**
     * Configures the label to be unidirected.
     * By default, the type is directed.
     * @return this EdgeLabelMaker
     * @see org.janusgraph.core.EdgeLabel#isUnidirected()
     */
    EdgeLabelMaker unidirected();
复制代码

意思是说创建边标签时默认是“directed”(有指向的),但这个“unidirected”是无指向的意思吗?

官网的解释是“单向边”(Unidirected Edges),注意这个和“入边”,“出边”的单个方向概念不一样。单向边占用更低的存储空间,但遍历受限。出顶点可以沿边遍历,但入顶点不知道它的存在。就像万维网中的【超链接】一样。

【请注意,删除其入顶点( in-vertex)时,不会自动删除未定向的边(Unidirected Edges)。参阅 Ghost Vertices

实测

测试场景

添加【刘备】--out--【兄弟】--in--> 【关羽】

测试方法

  • 创建边标签时分为directed和unidirected
  • 再分别使用addE方法(1)g.addE("brother").from(liubei).to(guanyu)和addEdge方法(2)liubei.addEdge("brother",guanyu)添加关系
  • 测试out/in查询语句:out是查刘备的兄弟,in是查关羽的兄弟

测试结果

能正确查出结果打√

类别 directed unidirected
out (1)
in (1) ×
out (2)
in (2) ×

结论

正向的out出边查询均正常

使用unidirected创建边标签后,关系不能入边(in)反向查询!!

directed(默认)创建边标签后,关系可以入边反向查询

刘备总有兄弟叫关羽,关羽却不一定有个兄弟叫刘备~


归档:【JanusGraph学习笔记】

相关专栏

怎么新建JanusGraph图并写入数据?

JanusGraph入门第一课-创建IDEA项目

JanusGraph学习笔记-问题与解决(一)

关注下面的标签,发现更多相似文章
评论