有朋友提到一個親屬圖譜推理的問題,下面分享一下自己的實現思路,僅供參考。
一、定義推理規則
提前定義一些關係推理規則,比如:
path=(a)<-[:父親]-(b)-[:姐姐]->(c)
則可以推斷出
path=(c)-[:父親]->(a)
就親屬關係而言這些規則是可以窮舉出來的。
二、隱含關係推理
在接口直接輸入兩個人的ID能得出來他們之間的隱含關係。
- 需要拿出兩個人之間的所有路徑,而不是最短路徑。
- 拿到所有路徑之後,每一條路徑都是一個有向的輸出序列,將所有有向序列整理到列表
- 將定義的規則拿到有向序列列表去匹配,這個匹配結果可能是多個的圖譜比較複雜的話可以考慮使用路徑擴展過程。路徑擴展
- 可以將挖掘出的隱含關係持久化到圖譜,也可以生成虛擬圖的方式返回。
#參考虛擬圖的生成過程
CALL apoc.create.vNode
CALL apoc.merge.vRelationship
- 注意點:在獲取路徑的時候,可以根據定義的規則路徑長度去獲取數據。比如:定義的規則路徑長度最多爲四層,那在獲取數據的時候最多獲取四層以內全部的路徑。
# 1.路徑長度和路徑序列獲取
MATCH (n),(m) WHERE id(n)=544 AND id(m)=1349
MATCH p=(n)-[*..4]-(m) WITH RELATIONSHIPS(p) AS paths,SIZE(RELATIONSHIPS(p)) AS pathSize SKIP 1 LIMIT 1
UNWIND paths AS path
RETURN TYPE(path),pathSize
# 2.路徑長度和路徑序列獲取
MATCH (n),(m) WHERE id(n)=544 AND id(m)=1349
MATCH p=(n)-[*..4]-(m) WITH RELATIONSHIPS(p) AS paths,SIZE(RELATIONSHIPS(p)) AS pathSize SKIP 1 LIMIT 1
RETURN paths,pathSize
# 3.路徑長度和路徑序列獲取
MATCH (n),(m) WHERE id(n)=544 AND id(m)=1349
MATCH p=(n)-[*..4]-(m) WITH RELATIONSHIPS(p) AS paths,SIZE(RELATIONSHIPS(p)) AS pathSize SKIP 1 LIMIT 1
UNWIND paths AS path
RETURN TYPE(path),ID(startNode(path)),ID(endNode(path)),pathSize
# 4.使用LENGTH函數獲取路徑長度
MATCH (n),(m) WHERE id(n)=544 AND id(m)=1349
MATCH p=(n)-[*..4]-(m) WITH RELATIONSHIPS(p) AS paths,LENGTH(p) AS pathSize SKIP 1 LIMIT 1
UNWIND paths AS path
RETURN TYPE(path),ID(startNode(path)),ID(endNode(path)),pathSize
三、通過算法插件進行隱含關係推理
上述方法是先獲取所有路徑再匹配的方式,還有一種方式是直接通過遍歷算法去控制獲取的路徑。這個方法比較高效。定義路徑遍歷的算法插件,遍歷規則使用自己定義的規則,關係有序遍歷,並且節點只經過人物類節點。