主要參考1:官方文檔;參考2:Neo4j和py2neo配合使用。
1.連接Neo4j
from py2neo import Graph # 導入 url = 'bolt://localhost:7687' # 本地連接地址 usr = 'neo4j' # 用戶名 key = '1' # 密碼 graph = Graph(url, auth = (usr, key)) # 連接到的圖
2. 節點創建和節點修改
寫在前面:使用py2neo對Neo4j進行修改,當我們直接用語法,Node或者Realation時,如果沒有進行綁定,就會僅僅是對本地端的數據進行了處理,而沒有作用到Neo4j上去,所以,在每一次處理完之后,一定要記得用graph.create或者graph.push將我們的處理傳遞到Neo4j上去。插入一段官網關於節點創建的描述,進行理解。英中(機翻)對照:
Node objects can either be created implicitly, by returning nodes in a Cypher query such as , or can be created explicitly through the constructor. In the former case, the local Node object is bound to the remote node in the database; in the latter case, the Node object remains unbound until create or merged into a Neo4j database.
CREATE (a) RETURN a
節點對象可以通過Cypher查詢中的返回節點(如)進行隱式創建,也可以通過構造器明確創建。在前一種情況下,本地節點對象與數據庫中的遠程節點綁定:在后一種情況下,節點對象保持未綁定,直到
創建
或合並
到 Neo4j 數據庫。
上面說到,如果創建節點,可以通過Cypher進行創建,或者通過構造器,而在使用構造器時,我們的節點對象由於未綁定,在Neo4j端其實是不發生變化的,需要再傳遞一下。
下面根據我個人學習和實際使用到的情況,逐步說明。
首先是簡單的節點操作。
2.1 創建一個新的節點
創建節點主要用Node函數,格式為 my_node = Node("label", name = 'XXX')。“label” 可以是我們給節點的一個分類,比如 “人物”,“地點”。最好是一個大類,這在我們檢索時,可以先確定,這個節點 “label” 是什么,之后再考慮填了什么內容。name 是一個屬性,屬性值就是里面的 “XXX”,在我們的瀏覽器圖示中節點展示的一般是 name 的屬性值。我們也可以加其他屬性和屬性值,key-value 對,格式和name = "XXX",一樣,逗號連接。同樣我們也可以給節點加多個標簽,直接在已有的 “label” 后面增加即可,逗號連接。
不要忘記用 create 把我們本地端的變化傳遞到連接的 Neo4j 上。graph.create() 用在創建時的連接。后面我們還會用到 create.push() 對已有節點或者關系的改動進行傳遞。
from py2neo import Graph, Node url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) a = Node('判決文書', name = 'XXX刑事判決書') # 創建一個label = '判決文書',屬性name值為',此時節點並沒有真的傳到Neo4j graph.create(a) # 將節點 a 創建到數據庫
下圖左是我們運行上面代碼后在瀏覽器查詢的結果,可以看到,節點顯示的是屬性name的值,並且有一個id,這個id是該節點的唯一標識。如果再運行一次代碼,就會創建一個內容一模一樣的節點,而 id 是不一樣的。這里就能發現一個問題,在創建節點時,create並不會自己檢查該節點是否已經創建,所以在實際使用,應先檢查要創建的節點是否存在。下圖右是查看的數據,可以看到labels為‘判決文書’,在左圖為黃色表示,這里稱為類別。name和值包含在properties屬性里,數據格式是像字典形式的。
2.2 查詢符合某條件的節點,不存在,則創建該節點
上面說到,Node 只管創建,有點像通信里的 “透明” 傳輸,它不會去看里面的內容是什么、是否一樣。這里就用查找函數幫我們看里面的內容,並進行篩選。由於我安裝的是最新穩定版的py2neo,所以語法上可能和其他 blog 里寫的略有區別。導入的是 matching 里的函數,有NodeMatcher,NodeMatch,用於節點的匹配,有RelationshipMatcher,RelationshipMatch,用於關系的匹配。此外,還可以直接通過 graph.match() 進行匹配,graph.match() 內部其實也是調用 Nodematcher 和 RelationshipMatcher 來實現的。
下面是關於節點的匹配。我們先創建一個節點匹配器 matcher 然后通過 matcher.match() 內部加入條件,對范圍進行確認,后綴 .exists() 是看該節點或該類節點是否存在,存在返回 bool 值True,否則返回 bool 值 False。.first() 是返回符合條件的一個節點。類型就是 Node。這里用了兩種方式進行條件的指定,一種是直接 match() 里寫,一種是利用 .where() 。where() 支持比較復雜的形式。
from py2neo import Graph, Node from py2neo.matching import * url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) matcher = NodeMatcher(graph) # 創建節點匹配器 result = matcher.match('判決文書', name = 'XXX刑事判決書').exists() # 符合條件的是否存在 print('節點是否存在:') print(result) if result == False: node = Node('判決文書', name = 'XXX刑事判決書') graph.create(node) else: node = matcher.match('判決文書').where(name = 'XXX刑事判決書').first() # 評估匹配並返回匹配的第一個節點 print('node') print(node) # 說明 # exist() 如果存在至少一個符合條件的節點,則返回True,否則返回False # 上面寫了兩種匹配方式,一種是直接在match里指定特點,一種是用where進行匹配,where可以進行精確匹配,可以用表達式進行較復雜的匹配
2.3 對已有節點進行標簽增加和屬性增改
用 node.add_label() 給節點增加標簽。用 node[“某屬性”] = “屬性值” 進行對節點進行 key-value 對的增加,很像字典的操作。此外,還有 node.setdefault("某屬性",default = “屬性值”) ,這個說明在代碼注釋中。
需要注意的是,上述修改完成后,一定要用 graph.push() 把變動傳遞到 Neo4j 上。
from py2neo import Graph, Node from py2neo.matching import * url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) matcher = NodeMatcher(graph) # 創建節點匹配器 node = matcher.match('判決文書').where(name = 'XXX刑事判決書').first() # 評估匹配並返回匹配的第一個節點 node.setdefault('審判程序', default = '刑事二審') # setdefault() 如果此節點具有的屬性value,則返回其值。如果沒有,添加‘審批程序’屬性和對應的屬性值 node.add_label('案件') node['案號'] = '001' # 添加“案號”屬性對應的屬性值為“001” print('node:') print(node) graph.push(node) # 將更改push到圖中 print('node:') print(node) # 說明:這里同樣寫了兩種增添方式,具體使用根據情況。可以看出第二種方式類似字典的形式的
其他函數:
移除標簽:node.remove_label(label)
2.4 獲取節點id和根據id查找節點
用 node.identity 獲取節點的 id ,用節點匹配器直接查找id = xxx 的節點。
from py2neo import Graph, Node from py2neo.matching import * url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) matcher = NodeMatcher(graph) # 創建節點匹配器 # 先創建一個節點 node = Node('人', name = '張三') graph.create(node) print(node) # 獲取該節點的id node_id = node.identity print(node_id) # 根據 id 查找節點 created_node = matcher[node_id] print(created_node) # 刪除節點 graph.delete(created_node) # graph.separate(created_node)
2.5 刪除節點
這一部分和創建類似,用graph.delete(node)即可。需要注意的這個節點也必須是我們已經從遠程匹配到的節點。graph.separate()也可以。delete可以傳遞的參數:節點,關系,圖和子圖。
為了控制篇幅,其他內容將在下節進行記錄。