neo4j图形数据库
一、下载
https://neo4j.com/download/ neo4j-community-3.5.12
二、安装
1.需要配置java环境
2.配置neo4j系统变量 NEO4J_HOME -> C: eo4j eo4j-community-3.5.12
3.配置neo4j环境变量 Path中添加%NEO4J_HOME%in
4.验证是否安装成功
C:Usersdaiszhan>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:Usersdaiszhan>neo4j install-service
三、开启服务
1.开启neo4j服务 C:Usersdaiszhan>neo4j start
2.关闭neo4j服务 C:Usersdaiszhan>neo4j stop
3.重启neo4j服务 C:Usersdaiszhan>neo4j restart
5.查看neo4j状态 C:Usersdaiszhan>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。