neo4j圖形數據庫
一、下載
https://neo4j.com/download/ neo4j-community-3.5.12
二、安裝
1.需要配置java環境
2.配置neo4j系統變量 NEO4J_HOME -> C:\neo4j\neo4j-community-3.5.12
3.配置neo4j環境變量 Path中添加%NEO4J_HOME%\bin
4.驗證是否安裝成功
C:\Users\daiszhan>neo4j.bat console 2019-11-07 03:08:25.943+0000 INFO ======== Neo4j 3.5.12 ======== 2019-11-07 03:08:25.991+0000 INFO Starting... 2019-11-07 03:08:30.949+0000 INFO Bolt enabled on 127.0.0.1:7687. 2019-11-07 03:08:33.013+0000 INFO Started. 2019-11-07 03:08:34.157+0000 INFO Remote interface available at http://localhost:7474/
5.通過訪問http://localhost:7474 默認跳轉到 http://localhost:7474/browser
默認用戶名和密碼為:neo4j,需要改自己的密碼eagleeye
6.注冊neo4j服務 C:\Users\daiszhan>neo4j install-service
三、開啟服務
1.開啟neo4j服務 C:\Users\daiszhan>neo4j start
2.關閉neo4j服務 C:\Users\daiszhan>neo4j stop
3.重啟neo4j服務 C:\Users\daiszhan>neo4j restart
5.查看neo4j狀態 C:\Users\daiszhan>neo4j status
四、安裝python包
pip install py2neo
五、使用py2neo
1.添加節點
from py2neo import Node, Relationship, Graph, NodeMatcher, RelationshipMatcher ## 新建圖形 graph = Graph('http://localhost:7474', username='neo4j', password='eagleeye') ## 新建節點 a = Node('label', name='a', id='0001', age=65, location='dalian') #第一個參數是類別,第二個參數是名字,可以有很多個參數名字 b = Node('label', name = 'b' )
## 給節點添加/修改屬性
a['age'] = 20 ## 繪制節點 graph.create(a) graph.create(b) ## 新建關系 r1 = Relationship(a, 'to', b, protocol = 'tcp') #a是開始節點,b是終止起點,to是二者關系類型,protocol是其他屬性,可以有很多個其他屬性 graph.create(r1)
## 給關系添加修改屬性
r1['state'] = 'up'
## 輸出節點, 關系
print(a)
(a:label {name='a',id='0001',age=65,lacation='dalian'})
print(r1)
(a)-[:to {protocol:"tcp"}]->(b)
## 對屬性進行批量更新
data={age:21,location:'shanghai'}
a.update(data)
2.對節點的操作
## 新建圖形 graph = Graph('http://localhost:7474', username='neo4j', password='eagleeye') ## 新建節點 a = Node('label', name='a', id='0001', age=65, location='dalian') # 返回節點的ID的哈希值 hash(a) # 返回節點屬性,沒有就返回None a[age] # 設定節點屬性值 a['type'] = 'ccc' # 刪除節點屬性,沒有會報KeyError del a['location'] # 返回節點屬性的數量 len(a) # 返回節點所有屬性 dict(a) # 返回一個生成器且只包含一個節點 walk(a) # 返回節點的標簽的集合 labels() # 判斷是否有這個標簽 a.has_label(location) # 給節點添加標簽 a.add_label(test) # 刪除節點標簽 a.remove_label(test) # 清除所有標簽 a.clear_labels() # 添加多個標簽 a.update_labels([test,test1])
3.對連接的操作
r1 = Relationship(a, 'to', b, protocol = 'tcp') #a是開始節點,b是終止起點,to是二者關系類型,protocol是其他屬性,可以有很多個其他屬性 graph.create(r1) # 返回關系的hash值 hash(r1) # 返回關系的屬性值 r1['state'] # 設定關系的屬性值 r1['state']='up' # 刪除關系的屬性值 del r1['state'] # 返回關系的屬性值數目 len(r1) # 以字典形式返回關系的所有屬性 dict(r1) # 返回一個生成器包含起始節點,關系,終止節點 walk(r1) # 返回關系類型 r1.type()
4.子圖
from py2neo import Node, Relationship a = Node('Person', name='Alice') b = Node('Person', name='Bob') r = Relationship(a, 'KNOWS', b) s = a | b | r print(s) >>> ({(alice:Person {name:"Alice"}), (bob:Person {name:"Bob"})}, {(alice)-[:KNOWS]->(bob)}) # 獲取所有的節點 s.nodes() # 獲取所有的關系 s.relationships() # 取交集 s1=a|b|r s2=a|b print(s1&s2) >>> ({(alice:Person {name:"Alice"}), (bob:Person {name:"Bob"})}, {}) print(s.keys()) >>> frozenset({'name'}) print(s.labels()) >>> frozenset({'Person'}) print(s.nodes()) >>>frozenset({(alice:Person {name:"Alice"}), (bob:Person >>> >>> >>> {name:"Bob"})}) print(s.relationships()) >>> frozenset({(alice)-[:KNOWS]->(bob)}) print(s.types()) >>> frozenset({'KNOWS'}) print(order(s)) >>> 2 print(size(s)) >>> 1 # 子圖擁有的屬性 subgraph | other | … 子圖的並 subgraph & other & … 子圖的交 subgraph - other - … 子圖的差 subgraph ^ other ^ … 子圖對稱差 subgraph.keys() 返回子圖節點和關系所有屬性的集合 subgraph.labels() 返回節點label的集合 subgraph.nodes() 返回所有節點的集合 subgraph.relationships() 返回所有關系的集合 subgraph.types() 返回所有關系的type的集合 order(subgraph) 返回子圖節點的數目 size(subgraph) 返回子圖關系的數目
5.遍歷
from py2neo import Node, Relationship a = Node('Person', name='Alice') b = Node('Person', name='Bob') c = Node('Person', name='Mike') ab = Relationship(a, "KNOWS", b) ac = Relationship(a, "KNOWS", c) w = ab + Relationship(b, "LIKES", c) + ac print(w) >>> (alice)-[:KNOWS]->(bob)-[:LIKES]->(mike)<-[:KNOWS]-(alice) ## 用walk()方法實現遍歷 from py2neo import walk for item in walk(w): print(item) # 從 a 這個 Node 開始遍歷,然后到 b,再到 c,最后重新回到 a >>> (alice:Person {name:"Alice"}) (alice)-[:KNOWS]->(bob) (bob:Person {name:"Bob"}) (bob)-[:LIKES]->(mike) (mike:Person {name:"Mike"}) (alice)-[:KNOWS]->(mike) (alice:Person {name:"Alice"}) print(w.start_node()) #獲取起始節點 >>> (alice:Person {name:"Alice"}) print(w.end_node()) #獲取終止節點 >>> (alice:Person {name:"Alice"}) print(w.nodes()) #所有節點的元祖 >>> ((alice:Person {name:"Alice"}), (bob:Person {name:"Bob"}), (mike:Person {name:"Mike"}), (alice:Person {name:"Alice"})) print(w.relationships()) #所有關系的元祖 >>> ((alice)-[:KNOWS]->(bob), (bob)-[:LIKES]->(mike), (alice)-[:KNOWS]->(mike))
6.查詢
6.1 傳統方式
graph = Graph() # 其中的數字對應的是節點,ID # 這個ID不按順序來的,要注意 graph.nodes[1234] graph.nodes.get(1234)
6.2 match方式
test_graph.data("MATCH (a:Person {name:'You'}) RETURN a") >>> [{'a': (c7d1cb9:Person {name:"You"})}] list(test_graph.run("MATCH (a:Person {name:'You'}) RETURN a")) >>>[('a': (c7d1cb9:Person {name:"You"}))] test_graph.run("MATCH (a:Person {name:'You'}) RETURN a").data() >>>[{'a': (c7d1cb9:Person {name:"You"})}] # 查詢關系 test_graph.run("MATCH (a:Person {name:'You'})-[b:FRIEND]->(c:Person {name:'Johan'} ) RETURN a,b,c") # graph查詢 graph.run("MATCH (n:leafCategory) RETURN n LIMIT 25").data() # list型 graph.run("MATCH (n:leafCategory) RETURN n LIMIT 25").to_data_frame() # dataframe型 graph.run("MATCH (n:leafCategory) RETURN n LIMIT 25").to_table() # table
6.3 find方式
# 節點個數 len(graph.nodes) len(graph.nodes.match("leafCategory")) # 某類別的節點個數 # 查找全部, 可根據label、property_key、property_value、limit查找 graph=test_graph.find(label='Person') for node in graph: print(node) >>> (b54ad74:Person {age:18,name:"Johan"}) (b1d7b9d:Person {name:"Rajesh"}) (cf7fe65:Person {name:"Anna"}) (d780197:Person {name:"Julia"}) # 查找單節點, 可根據label、property_key、property_value查找 test_graph.find_one(label='Person',property_key='name',property_value='You') >>> (c7d1cb9:Person {name:"You"}) # 該節點是否存在 test_graph.exists(graph.nodes[1234])
6.4 NodeMatcher方式(py2neoV4適用)
test_graph = Graph(password='123456') selector = NodeMatcher(test_graph) #selector = NodeSelector(test_graph) 適用py2neoV3 list(selector.select("Person", name="Anna")) #篩選 age 為 21 的 Person Node list(selector.select("Person").where("_.name =~ 'J.*'", "1960 <= _.born < 1970")) #排序功能 persons = list(selector.select('Person').order_by('_.age')) # 主要方法 first()返回單個節點 limit(amount)返回底部節點的限值條數 skip(amount)返回頂部節點的限值條數 order_by(*fields)排序 where(*conditions, **properties)篩選條件
6.5 match()或match_one()
for rel in test_graph.match(start_node=node3, rel_type="FRIEND"): print(rel.end_node()["name"]) >>> Johan Julia Andrew # match_one test_graph.match_one(start_node=node3, rel_type="FRIEND") >>> (c7d1cb9)-[:FRIEND]->(b54ad74)
7.更新
## push的用法 node = test_graph.find_one(label='Person') node['age'] = 18 test_graph.push(node) print(test_graph.find_one(label='Person')) >>> (b54ad74:Person {age:18,name:"Johan"}) ## update() 方法 ## setdefault()方法 ## 直接賦值法,會覆蓋原有的
8.刪除
delete(subgraph) 刪除節點、關系或子圖 delete_all() 刪除數據庫所有的節點和關系 from py2neo import Graph graph = Graph(password='123456') node = graph.find_one(label='Person') relationship = graph.match_one(rel_type='KNOWS') graph.delete(relationship) graph.delete(node) # 在刪除 Node 時必須先刪除其對應的 Relationship,否則無法刪除 Node。
參考文檔 http://neo4j.com.cn/public/docs/index.html