> 技术文档 > python 与 neo4j 交互(py2neo 使用)

python 与 neo4j 交互(py2neo 使用)

参考自:neo4j的python.py2neo操作入门
官方文档:The Py2neo Handbook — py2neo 2021.1
安装:pip install py2neo -i https://pypi.tuna.tsinghua.edu.cn/simple

1 节点 / 关系 / 属性 / 路径

节点(Node)和关系(relationship)是构成图的基础,节点和关系都可以有多个属性(property),并且均可以作为实体

重点:

  1. 节点:在图数据库中,节点代表实体,可以拥有属性和标签。节点通常用来表示实际的数据实体,比如人、地点、事件等
  2. 关系:关系描述了节点之间的连接或关联,必须包含两个节点,且具有方向:start node →end node
  3. 路径:路径是由节点和关系组成的序列,描述了节点之间的连接路径。路径是一个完整的图形结构,由起始节点、关系和结束节点组成,表示了实体之间的关系和连接方式
  4. 属性:键-值(key-value),键是字符串类型,值,可以是原数据,也可以由原数据同类型的数组
  5. 对于一个节点来说,与之相连的关系是有输入和输出两个方向。(如node2有输入关系和输出关系:node1→node2→node3),这个特性对于遍历图很重要
  6. 一个节点可以有一个关系是指向自己的

2 连接neo4j

前置安装:
配套资料:配套资料
安装Neo4j
下载配套资料中的neo4j-community-3.5.5-windows和jdk-11.0.2_windows-x64_bin
neo4j解压即可,jdk就常规安装
完成之后需要将neo4j和jdk的bin目录都配置为环境变量(即path中,若不懂请自行百度)

验证安装:
cmd窗口下 java -version
注: 若之前配置过jdk,需要将新配置的jdk上移到环境变量的最上方,或者直接删除以前配置过的jdk,然后重新打开cmd窗口进行验证安装

cmd下启动Neo4j
neo4j.bat console

访问http://localhost:7474/,用户名和密码都输入neo4j,并连接(注意命令行窗口不能关闭),之后重新设置密码(建议设置为123456)

#cmd窗口下
neo4j.bat console
浏览器访问 http://localhost:7474/

3 创建图对象

from py2neo import Graph, Subgraphfrom py2neo import Node, Relationship, Path# 连接数据库# graph = Graph(\'http://localhost:7474\', username=\'neo4j\', password=\'123456\') # 旧版本graph = Graph(\'bolt://localhost:7687\', auth=(\'neo4j\', \'123456\'))# 删除所有已有节点graph.delete_all()

4 数据类型及操作

4.1 Node:节点

基本语法:Node(*labels,**properties)

# 定义nodenode_1 = Node(\'英雄\',name = \'张无忌\')node_2 = Node(\'英雄\',name = \'杨逍\',武力值=\'100\')node_3 = Node(\'派别\',name = \'明教\')# 存入图数据库graph.create(node_1)graph.create(node_2)graph.create(node_3)print(node_1)

python 与 neo4j 交互(py2neo 使用)

4.2 Relationship:关系

基本语法:Relationship((start_node, type, end_node, **properties))

# 增加关系node_1_to_node_2 = Relationship(node_2,\'教主\',node_1)node_3_to_node_1 = Relationship(node_1,\'统领\',node_3)node_2_to_node_2 = Relationship(node_2,\'师出\',node_3)graph.create(node_1_to_node_2)graph.create(node_3_to_node_1)graph.create(node_2_to_node_2)

python 与 neo4j 交互(py2neo 使用)

4.3 Path:路径

基本语法:Path(*entities)
注:entities是实体

# 建一个路径:比如按照该路径查询,或者遍历的结果保存为路径node_4,node_5,node_6 = Node(name=\'阿大\'),Node(name=\'阿三\'),Node(name=\'阿二\')path_1 = Path(node_4,\'小弟\',node_5,Relationship(node_6, \"小弟\", node_5),node_6) # (阿大)-[:小弟 {}]->(阿三)<-[:小弟 {}]-(阿二)graph.create(path_1)print(path_1)

python 与 neo4j 交互(py2neo 使用)

4.4 Subgraph:子图

节点和关系的任意集合,它也是 Node、Relationship 和 Path 的基类
基本语法:Subgraph(nodes, relationships)
空子图表示为None,使用bool()可以测试是否为空,且参数要按数组输入

# 创建一个子图,并通过子图的方式更新数据库node_7 = Node(\'英雄\',name = \'张翠山\')node_8 = Node(\'英雄\',name = \'殷素素\')node_9 = Node(\'英雄\',name = \'狮王\')relationship7 = Relationship(node_1,\'生父\',node_7)relationship8 = Relationship(node_1,\'生母\',node_8)relationship9 = Relationship(node_1,\'义父\',node_9)subgraph_1 = Subgraph(nodes = [node_7,node_8,node_9],relationships = [relationship7,relationship8,relationship9])graph.create(subgraph_1)

python 与 neo4j 交互(py2neo 使用)

4.5 工作流

(1)GraphService:基于图服务的工作流。
(2)Graph:基于图数据库的工作流(前文所述的基本上都是如此)。
(3)Transaction:基于事务的工作流
在一个事务里,进行多种操作,只有操作全部完成,工作流才算完成,如:
一个Transaction分两个任务:① 增加一个新节点 ② 将该节点与已有节点创建新关系
两个任务只要有一个没完成,整个工作流就不会生效
通常,该种方式通过Graph.begain(readonly=False)构造函数构造,参数readonly表示只读,无参数默认可写

# 创建一个新的事务transaction_1 = graph.begin()# 创建一个新nodenode_10 = Node(\'武当\',name = \'张三丰\')transaction_1.create(node_10)# 创建两个关系:张无忌→(师公)→张三丰 张翠山→(妻子)→殷素素relationship_10 = Relationship(node_1,\'师公\',node_10)relationship_11 = Relationship(node_7,\'妻子\',node_8)transaction_1.create(relationship_10)transaction_1.create(relationship_11)transaction_1.commit()

python 与 neo4j 交互(py2neo 使用)

4.6 删

# 删除所有:谨慎使用# graph.delete_all()# 按照节点id删除:要删除某个节点之前,需要先删除关系。否则会报错:ClientErrorgraph.run(\'match (r) where id(r) = 3 delete r\')# 按照name属性删除:先增加一个单独的节点:node_x = Node(\'英雄\',name =\'韦一笑\')graph.create(node_x)graph.run(\'match (n:英雄{name:\\\'韦一笑\\\'}) delete n\')# 删除一个节点及与之相连的关系graph.run(\'match (n:英雄{name:\\\'韦一笑\\\'}) detach delete n\')# 删除某一类型的关系graph.run(\'match ()-[r:喜欢]->() delete r;\')# 删除子图# delete(self, subgraph)

4.7 改

# 将node_9狮王的武力值改为100node_9[\'武力值\']=100# 本地修改后要push到服务器上graph.push(node_9)

python 与 neo4j 交互(py2neo 使用)

4.8 查

为了使用更复杂查询,将图数据库扩充如下:

# 为了便于查询更多类容,新增一些关系和节点transaction_2 = graph.begin()node_100 = Node(\'巾帼\',name =\'赵敏\')re_100 = Relationship(node_1,\'Love\',node_100)node_101 = Node(\'巾帼\',name =\'周芷若\')re_101 = Relationship(node_1,\'knows\',node_101)re_101_ = Relationship(node_101,\'hate\',node_100)node_102 = Node(\'巾帼\',name =\'小昭\')re_102 = Relationship(node_1,\'konws\',node_102)node_103 = Node(\'巾帼\',name =\'蛛儿\')re_103 = Relationship(node_103,\'Love\',node_1)transaction_2.create(node_100)transaction_2.create(re_100)transaction_2.create(node_101)transaction_2.create(re_101)transaction_2.create(re_101_)transaction_2.create(node_102)transaction_2.create(re_102)transaction_2.create(node_103)transaction_2.create(re_103)transaction_2.commit()

python 与 neo4j 交互(py2neo 使用)

① NodeMatcher:定位满足特定条件的节点
基本语法:NodeMatcher.match(*labels, **properties)

方法名 功能 first() 返回查询结果第一个Node,没有则返回空 all() 返回所有节点 where(condition,properties) 二次过滤查询结果 order_by 排序
# 定义查询nodes = NodeMatcher(graph)# 按照label查询所有节点node_hero = nodes.match(\"英雄\").all()print(\'查询结果的数据类型:\',type(node_hero))# 按property查询,返回符合要求的首个节点:name-杨逍node_single = nodes.match(\"英雄\", name=\"杨逍\").first()print(\'单节点查询:\\n\', node_)# 按property查询,返回符合要求的所有节点node_name = nodes.match(name=\'张无忌\').all()print(\'name查询结果:\', node_name)# 在查询结果中循环取值i = 0for node in node_hero: print(\'label查询第{}个为:{}\'.format(i,node)) i+=1# get()方法按照id查询节点node_id = nodes.get(1)print(\'id查询结果:\', node_id)

② NodeMatch
基本用法:NodeMatch(graph, labels=frozenset({}), predicates=(), order_by=(), skip=None, limit=None)

方法 功能 iter(match) 遍历所匹配节点 len(match) 返回匹配到的节点个数 all() 返回所有节点 count() 返回节点计数,评估所选择的节点 limit(amount) 返回节点的最大个数 order_by(*fields) 按指定的字段或字段表达式排序 要引用字段或字段表达式中的当前节点,请使用下划线字符 where(*predicates, **properties) 二次过滤
from py2neo import NodeMatchnodess = NodeMatch(graph, labels=frozenset({\'英雄\'}))# 遍历查询到的节点print(\'=\' * 15, \'遍历所有节点\', \'=\' * 15)for node in iter(nodess): print(node)# 查询结果计数print(\'=\' * 15, \'查询结果计数\', \'=\' * 15)print(nodess.count())# 按照武力值排序查询结果:注意引用字段的方式,前面要加下划线和点:_.武力值print(\'=\' * 10, \'按照武力值排序查询结果\', \'=\' * 10)wu = nodess.order_by(\'_.武力值\')for i in wu: print(i)

③ RelationshipMatcher:用于选择满足一组特定标准的关系的匹配器
基础语法:relation = RelationshipMatcher(graph)

from py2neo import RelationshipMatcher# 查询某条关系relation = RelationshipMatcher(graph)# None表示any node,而非表示空print(\'=\'*10,\'hate关系查询结果\',\'=\'*10)x = relation.match(nodes=None, r_type=\'hate\')for x_ in x: print(x_)# 增加关系re1_1 = Relationship(node_101,\'情敌\',node_102)re1_2 = Relationship(node_102,\'情敌\',node_103)graph.create(re1_1)graph.create(re1_2)# 情敌查询结果print(\'=\'*10,\'hate关系查询结果\',\'=\'*10)x = relation.match(nodes=None, r_type=\'情敌\')for x_ in x: print(x_) 

④ RelationshipMatch
基本语法:RelationshipMatch(graph, nodes=None, r_type=None, predicates=(), order_by=(), skip=None, limit=None)
用法类同,不再赘述