文章目录
- py2neo介绍
- 连接Neo4j数据库
- py2neo查询图数据库neo4j
- 数据概览
- 使用NodeMatcher查询节点
- 使用RelationshipMatcher查询关系
- 通过执行Cypher语句查询
py2neo介绍
Neo4j
是一款开源图数据库,Py2neo
提供了使用Python语言访问Neo4j
的接口。本文介绍了使用Py2neo
的NodeMatcher
和RelationshipMatcher
查询图中的节点和关系,以及通过执行Cypher
语句的查询方式。
py2neo
版本:2021.2.4
连接Neo4j数据库
from py2neo import Graph, Node, Relationship
# 连接neo4j数据库,输入地址、用户名、密码
graph = Graph("http://localhost:7474", name="neo4j", password='admin')
py2neo查询图数据库neo4j
数据概览
通过graph.schema
查询图中节点和关系有哪些类型
graph.schema.node_labels #查询节点类型
frozenset({'album', 'person', 'song'})
graph.schema.relationship_types #查询关系类型
frozenset({'专辑', '作词', '所属专辑', '歌手'})
使用NodeMatcher查询节点
首先创建一个NodeMatcher
对象,用match
来指明要匹配哪种label
的节点,用where
来表示筛选条件(有两种方法)。
需要注意的是,匹配成功返回的是NodeMatcher
的对象,要转化成Node
对象,可以用first
取出符合条件的第一个节点,或者转化成节点的list
。
from py2neo import NodeMatcher
node_matcher = NodeMatcher(graph) # 节点匹配器
a = node_matcher.match('person',name='周杰伦').all() # 提取满足属性值的节点
a
[Node('person', name='周杰伦')]
本数据库中基本没有添加节点的属性,所以where
函数的用处不大。
where
条件有两种写法,一种是把要匹配的属性和值写成key=value
的形式,例如where(age=20)
,这种写法只能按照值是否完全一致来匹配,不能按照值的大小来筛选。
想要按照值的大小筛选或者做一些字符串的模糊匹配,可以把条件表达式写成一个字符串,整体放在where
语句中,在这个字符串中,可以用 _
来代指匹配到的节点。
node = node_matcher.match("Person").where("_.work =~ '月亮.*'").first()
>>>node
Node('Person', 'Teacher', age=45, name='赵赵', work='月亮中学')
>>>nodes = list(node_matcher.match("Person").where("_.age > 20"))
>>>nodes
[Node('Person', age=35, name='王王', work='宇宙电子厂'),
Node('Person', age=30, name='张张', work='宇宙电子厂'),
Node('Person', 'Teacher', age=45, name='赵赵', work='月亮中学')]
将NodeMatcher
返回的结果转化为Node
数据类型或者Node
的list
之后,访问其中的属性也就十分简单了,如上面最后一例的结果,访问其中第一个节点的name
属性:
print(a[0].get('name'))
print(a[0]['name'])
周杰伦
周杰伦
使用RelationshipMatcher查询关系
RelationshipMatcher
的match
方法有三个及以上参数:
- 第一个参数是节点的序列或者
set
,可以为None
,为None
表示任意节点均可; - 第二个参数是关系的类型,可以为
None
,为None
表示任意类型的关系均可; - 第三个参数开始是要匹配的属性,写成
key=value
的形式。
match
方法的返回值是RelationshipMatcher
类型,需要通过first
转化成Relationship
数据结构,或者转化为list
。
eg
. 查询所有和蔡依林有关系的实体节点,r_type=None
代表提取任意关系。
from py2neo import RelationshipMatcher
relation_matcher = RelationshipMatcher(graph) # 关系匹配器
node1 = node_matcher.match("person").where(name='蔡依林').first()
relations = relation_matcher.match([node1],r_type=None) # 提取特别属性的关系
for rel in relations:
print(rel)
(蔡依林)-[:作词 {}]->(毛毛)
(蔡依林)-[:歌手 {}]->(城堡)
查询图中某一类关系,第一个参数为None
,第二个参数r_type
指定关系类型,这里查询所有的 所属专辑 类型。
relations = relation_matcher.match(None,r_type='所属专辑') # 提取特别属性的关系
for rel in relations:
print(rel)
(Mine Mine)-[:所属专辑 {}]->(惊叹号)
(Now You See Me)-[:所属专辑 {}]->(周杰伦的床边故事)
(阿爸)-[:所属专辑 {}]->(恋花)
(爱的飞行日记)-[:所属专辑 {}]->(跨时代)
(爱你没差)-[:所属专辑 {}]->(12新作)
(爱情废柴)-[:所属专辑 {}]->(周杰伦的床边故事)
(爱情悬崖)-[:所属专辑 {}]->(叶惠美)
(爱在西元前)-[:所属专辑 {}]->(范特西)
(安静)-[:所属专辑 {}]->(范特西)
(暗号)-[:所属专辑 {}]->(八度空间)
(爸,我回来了)-[:所属专辑 {}]->(范特西)
(白色风车)-[:所属专辑 {}]->(依然范特西)
(依然范特西)-[:所属专辑 {}]->(回想曲青青校树)
(半岛铁盒)-[:所属专辑 {}]->(八度空间)
Relationship
其实是包含了一对起止节点:start_node
和end_node
,包含了关系的类型,而关系的属性是以字典形式存在的,可以用get
方法来获取属性的值。
relations = list(relation_matcher.match(None,r_type='所属专辑')) # 提取特别属性的关系
print(relations[0].start_node['name'])
print(relations[0].end_node['name'])
print(type(relations[0]).__name__)
Mine Mine
惊叹号
所属专辑
通过执行Cypher语句查询
NodeMatcher
和RelationshipMatcher
能够表达的匹配条件相对简单,更加复杂的查询还是需要用Cypher
语句来表达。
Py2neo
本身支持执行Cypher
语句的执行,可以将复杂的查询写成Cypher
语句,通过graph.run
方法查询,返回的结果可以转化为pandas.DataFrame
或者pandas.Series
对象,从而和其他数据分析工具无缝衔接。