這里接着上一篇的內容,進行關系的創建和關系的查找。
關系的創建和查找
1 創建兩個節點間的關系
創建關系時用函數 Relationship() 函數。格式為relation = Relationship(start_node, relationship, end_node) 。start_node為開始節點,end_node為結束節點,relationship 為兩節點間的關系。需要知道的是,Neo4j 的關系都是有向的,這里的關系詞是由start_node 指向 end_node 的關系。創建后,通過graph.create(relation) 導入Neo4j。
from py2neo import Graph, Node, Relationship from py2neo.matching import * url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) node_matcher = NodeMatcher(graph) case = node_matcher.match('判決文書', name = 'XXX刑事判決書').first() # 獲得name為XXX刑事判決文書的“判決文書”類 節點 people = node_matcher.match('被告人','人', name = 'XXX').first() # 獲得name為“XXX”的“被告人”類節點 relation = Relationship(case, '被告人', people) # 創建判決文書和被告人間的關系,關系詞為“被告人” graph.create(relation) # 將創建傳遞到圖上
如果創建新的節點和對應的關系怎么辦,很簡單,先創建節點,再創建關系(注意哦,這個和后續可能的刪除順序是相反的),比如下面示例。我們就不用查詢已有節點的,直接將創建的節點用Relationship 連接就好了。但是可能 create 需要逐步來。我自己嘗試的時候是不能批量 create 的,如果是需要批量創建節點,建議直接查詢 Neo4j 批量創建節點尋找方法,Neo4j 是提供多種批量導入方式的。
2 查找以某種關系直接連接的兩個節點
前面在查詢節點時,用到的是NodeMatcher。在查詢關系時會類似用到RelationshipMatcher,下面直接給出查詢兩者有直接相連關系的例子。並把我遇到問題進行總結。希望對大家也有所幫助。
首先,來看relation_matcher() 函數的格式。relation_matcher({start-node, end-node}, r_type = XXX, key = value)。這里有三組參數,第一組在 {} 里是起始節點和終止節點,對節點做出限制,可以是None;第二組是關系類型 r_type,第三組是鍵值組合。這些都可以用在關系查找中,對我們的關系進行限制。在下面例子中,可以看到,relation_matcher() 后面也可以接如.first() 等函數進行補充,比如.where() 用表達式對關系進行限制,用.limit() 限制查找的數量,還有之前出現多次的.exists() 確定是否存在。
接着,來說一說我遇到的問題:
1)能不能查詢比較深度的關系,必須直接相連嗎,之間隔着一個節點可以嗎?我的嘗試是不能。如果有朋友嘗試出了可以分享一下。
2)在我使用該函數的例子中,如果節點確實存在,確實存在直接的連接關系,是可以正確查詢的。
3)使用graph.match() 傳同樣的參數,是可以替代relation_matcher.match() 的
4)如果我們在 node_matcher.match 部分查找到的其中一個節點結果為空,即這個節點不存在,就會傳入空節點。這樣會查詢另外一個節點(認為這個節點不空)所以與之直接相連符合條件的結果。
from py2neo import Graph, Node, Relationship from py2neo.matching import * url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) node_matcher = NodeMatcher(graph) # 節點匹配器 relation_matcher = RelationshipMatcher(graph) # 關系匹配器 # 要被查詢關系的兩個節點,注意,這里不能時自己直接node一個再去匹配的,對於匹配來說,只有連接的graph中存在的節點,才可以被讀入。所以我們先要獲取一下。內容有重復的節點,不影響 first_node = node_matcher.match('人', name = '張三').first() second_node = node_matcher.match('職業', name = '法外狂徒').first() result = relation_matcher.match({first_node, second_node}, r_type = None, key = value).first() # 查詢結果的格式我們是不能直接讀的,可以用.first(),或者對結果list,即list(result) print(result) # 打印結果,格式一般是 (節點一)-[關系]->(節點二) print(result.nodes) # 打印節點 graph.separate(relation) # 刪除關系 # graph.delete(relation) # 刪除關系
3 關系的刪除
單獨刪除關系用函數graph.separate(relationship)。當我們需要刪除大圖中的一部分節點時,需要先刪除關系再刪除節點,這時候就會用到這個函數。具體使用在上面的代碼中已經實現。separate可以傳的參數有關系、節點、圖和子圖。delete同樣
