py2neo连接neo4j
连接数据库,创建游标
'''
py2neo每隔一段时间自动销毁连接
'''
from py2neo import Graph, Node, Relationship,Subgraph
graph = Graph('http://localhost:7474', username='neo4j', password='neo4j')
cursor = graph.begin()
创建节点
node1 = Node('概念实体', name='1')
node2 = Node('实例实体', name='2')
'''
info = {'name':3,'type':4}
node3 = Node('实例实体', **info)
'''
cursor.create(node1)
cursor.create(node2)
#提交
cursor.commit()
查询节点
用正则模糊查询时前面加~
match (s) where s.name=~'.*名字.*' return s
#有的版本会报错,有的还可以用,.first()只查符合条件的第一个节点
node = graph.nodes.match(name='1',type='2').first()
#方法一
nodes = graph.nodes.match("概念实体").where("_.name='1' and _.type='2'").data()
#只查符合条件的第一个节点
#node = graph.nodes.match("概念实体").where("_.name='1'").first()
for node in nodes:
print(node)
#节点的标签,这里即{'概念实体'}
print(node._labels)
#节点的属性
print(node['name'])
#方法二
'''
match_str ="match (s{name:$my_name}) return s"
nodes = graph.run(match_str, parameters = {'my_name':'myName'}).data()
'''
match_str ="match (s{name:'myName'}) return s"
#match_str = "match (s:{}) where s.name={} return s".format('概念实体',"'1'")
nodes = graph.run(match_str).data()
for node in nodes:
#节点实际是node['s']
print(node)
#节点的标签,这里即{'概念实体'}
print(node['s']._labels)
#节点的属性
print(node['s']['name'])
#方法三
match_str = "match (s:概念实体) where s.name='1' and s.type='2' return s"
#match_str = "match (s:{}) where s.name={} return s".format('概念实体',"'1'")
nodes = graph.run(match_str).data()
for node in nodes:
#节点实际是node['s']
print(node)
#节点的标签,这里即{'概念实体'}
print(node['s']._labels)
#节点的属性
print(node['s']['name'])
更新节点
nodes = graph.nodes.match().data()
new_nodes = list(nodes)
## 添加你要修改的东西
for node in new_nodes:
node['name'] = node['name'] + 'aa'
# 里面是Node的list可以作为Subgraph的参数
sub = Subgraph(nodes=new_nodes)
cursor.push(sub)
cursor.commit()
'''
with从句可以连接多个查询的结果,即将上一个查询的结果用作下一个查询的开始。
两种用法:
1、通过使用oder by 和limit,with可以限制传入下一个match子查询语句的实体数目。
2、对聚合值过滤。
例如:
#合并名字一样的节点
match_str = "MATCH (n) with n.name as name,collect(n) as nodelist,count(n) as nodecount where nodecount > 1 call apoc.refactor.mergeNodes(nodelist) YIELD node RETURN count(node)"
#合并重复关系
match_str = "MATCH (a)-[r]-(b) WITH a, b, collect(r) as rels CALL apoc.refactor.mergeRelationships(rels,{properties:'combine'}) YIELD rel RETURN count(rel)"
'''
删除节点
match_str = "match (s:{}) where s.name={} return s".format('概念实体',"'1'")
nodes = graph.run(match_str).data()
for node in nodes:
cursor.delete(node['s'])
#提交
cursor.commit()
创建关系
node1 = Node('概念实体', name='1')
node2 = Node('实例实体', name='2')
#创建节点
cursor.create(node1)
cursor.create(node2)
#创建关系
cursor.create(Relationship(node2, '包含', node1, name = '属性'))
#提交
cursor.commit()
关系查询
'''
这里遇到一个问题:
直接打印对应字典时,返回为{}
print(dict(node['r'].start_node))
解决:
先加载一次后返回正常
node['r'].start_node.__str__()
print(dict(node['r'].start_node))
'''
#通过实体关系查询另一实体
#match_str = "match (m:概念实体{name:'1'})<-[包含]-(n:实例实体) return n"
match_str = "match (m:概念实体)<-[包含]-(n:实例实体) where m.name='1' return n"
nodes = graph.run(match_str).data()
for node in nodes:
print(node)
#通过两实体查询关系(需要先加载过两实体)
graph.nodes.match("概念实体").where("_.name='1'").first()
graph.nodes.match("实例实体").where("_.name='2'").first()
match_str = "match (m:概念实体)<-[r]-(n:实例实体) where m.name='1' and n.name='2' return m,r,n"
nodes = graph.run(match_str).data()
for node in nodes:
print(node['r'])
print(node['r'].start_node)
print(node['r'].end_node)
#打印具体关系、实体属性
print(node['m']['name'])
print(node['r']['level'])
#关系名
name = str(*node['r'].types())
print(name)
print(list(node['r'].types())[0])
print(re.findall('-\[:(.*?) {}\]-',str(node['r']))[0])
#实体属性
print([(k,v) for k,v in node['r'].start_node.items()])
print([(k,v) for k,v in node['r'].end_node.items()])
#节点的标签,这里即{'概念实体'}
print(node['m']._labels)
#查询所有关系
graph.nodes.match("概念实体").where("_.name='1'").first()
graph.nodes.match("实例实体").where("_.name='2'").first()
# 查询为'包含'的关系
# rs = graph.relationships.match(r_type='包含')
rs = graph.relationships.match().data()
for r in rs:
print(r)
print(r.start_node)
print(r.end_node)
删除关系
#方法一
#通过两实体删除关系(需要先加载过两实体)
graph.nodes.match("概念实体").where("_.name='1'").first()
graph.nodes.match("实例实体").where("_.name='2'").first()
match_str = "match (m:概念实体)<-[r]-(n:实例实体) where m.name='1' and n.name='2' return r"
rs = graph.run(match_str).data()
for r in rs:
graph.delete(r['r'])
cursor.commit()
#方法二
#通过两实体删除关系(需要先加载过两实体)
graph.nodes.match("概念实体").where("_.name='1'").first()
graph.nodes.match("实例实体").where("_.name='2'").first()
match_str = "match (m:概念实体)<-[r]-(n:实例实体) where m.name='1' and n.name='2' delete r"
rs = graph.run(match_str)
cursor.commit()
删除所有节点关系
graph.delete_all()