一網打盡JanusGraph"出邊入邊無向邊雙向邊"
起因參考我之前建立圖資料表的操作,要給“劉備”和“關羽”新增【兄弟】關係,要分別輸入劉備有個兄弟叫關羽,關羽有個兄弟叫劉備,神煩!
問題
在網上搜查了半天愣是沒找到怎麼給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學習筆記】