起因参考我之前创建图数据表的操作,要给“刘备”和“关羽”添加【兄弟】关系,要分别输入刘备有个兄弟叫关羽,关羽有个兄弟叫刘备,神烦!
问题
在网上搜查了半天愣是没找到怎么给jg图数据库的2个顶点添加一个双向的关系,无奈翻了下官网和源码,整理分享如下:
JanusGraph有双向边吗?
先说答案:"没有"。
需要双向边怎么办?
"如果需要双向边,则通过添加两条相反方向的单向边实现。"
建议使用时封装一个方法即可。
边的方向
看源码的org.janusgraph.graphdb.relations.EdgeDirection:
public class EdgeDirection {
public static final Direction[] PROPER_DIRS = {Direction.IN, Direction.OUT};
……
}
白纸黑字仅有IN和OUT两个方向。
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学习笔记】