当前位置:   article > 正文

【py2neo学习笔记】利用py2neo库来操作neo4j 知识图谱的创建、增加、删除、修改、查询、案例、参考博客_neo2py

neo2py
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

# 参考文档1 从增删改角度: https://blog.csdn.net/qq_42644523/article/details/127438757
# 参考文档2 从常用方法介绍和与Cypher原语句对比: https://zhuanlan.zhihu.com/p/81175725
# 参考文档3 实例(用于检验前两个学习是否掌握): https://huaweicloud.csdn.net/63808884dacf622b8df89a37.html

# -----------------------
# ----  准备工作  -------
# -----------------------
# 导包
import py2neo
from py2neo import Graph, Node, Relationship, RelationshipMatcher, NodeMatcher

# -----------------------
# ---  节点与关系初始化  ---
# -----------------------
# 图的初始化
graph = Graph("http://localhost:7474",user ="",password='')
# 用pycharm打开neo4j工作台连接,默认的端口号就是7474,输入自己的账号密码


# 节点 = Noede(节点标签,属性名1=属性值1,属性名2,属性值2...)
# nodex = Node(*labels,**properties)
node1 = Node('Person', name='tony', age=25, weight=55)
node2 = Node('Person', name='tom', age=23, weight=50, hight=170)
node3 = Node('Person','male','Suspect', name='peter', age=22, weight=48, hight=165)
node4 = Node('Person','female',name='lisa', age=21, weight=46)
node5 = Node('Person')

# 关系规则
# relationx = Relationship(nodestart, "关系类型", nodeend, 属性1=属性值1,属性2,属性值2...)
relation1 = Relationship(node1, "KNOW", node2)
relation2 = Relationship(node1, 'KNOW', node3, strong=85)
relation3 = Relationship(node1, 'COUPLE', node4, value=90)
relation4 = Relationship(node4, 'MATE', node2, strong=40)
relation5 = Relationship(node2, 'KNOW', node3, strong=60)

# -----------------------
# ------    创    --------
# ------------------------

# 在图中添加节点
# graph.create(节点)
graph.create(node1)
graph.create(node2)
graph.create(node3)
graph.create(node4)
graph.create(node5)
# graph.create(Node(节点属性,属性1=属性值1))

# 在图中添加关系
# graph.create(关系)
graph.create(relation1)
graph.create(relation2)
graph.create(relation3)
graph.create(relation4)
graph.create(relation5)

# -----------------------
# --- 查看数据库基本属性 ---
# -----------------------
graph.schema.node_labels # 查看图结构中节点标签的类别 type(_) = frozenset
graph.schema.relationship_types # 查看图结构中关系的类型

# -----------------------
# ------    增    --------
# -----------------------

# 增加标签
# 节点.add_label(标签)
node1.add_label('male')
graph.push(node1)# 略

# 批量增加节点标签
node2.update_labels(['male','Suspect'])
graph.push(node2)# 略

# 增加节点属性
# 节点[属性名] = 属性值
# 增加本来没有的属性
# 初始状态node1 (标签:'Person', 属性1 name='tony', 属性2 age=25, 属性3 weight=55)
node1['hight'] = 190
# 修改后的状态,是在原来的基础上,增加了属性4?
# 修改原本已经有的属性(改的内容,放在一起看)
node1['age'] = 26
graph.push(node1)# 略

# 增加关系的属性
relation2['strong'] = 90
graph.push(relation2)# 略


# -----------------------
# ------    删    --------
# -----------------------

# 删除节点标签
# 节点.remove_label(标签)
node3.remove_label('Suspect')
graph.push(node3)# 略

# 删除节点属性
# del 节点[属性名]
del node1['age']
graph.push(node1)# 略

# 删除整个节点但不删除关系
# 注! 不等于把关系一同删除了,所以我觉得应该是很少用的
graph.delete(node5)
# 删完之后不用push

# 删除关系属性
# del 关系[属性名]
del relation3['value']
graph.push(relation3)# 略

# 删除关系组,例如:将与目标节点相关的节点的所有关系都删除掉
# relation = RelationshipMatcher(graph)
# 关系组 = relation.match(nodes=[节点1,节点2],r_type = 关系类型,limit=None)
# for 关系 in 关系组:
#     graph.separate(关系)

# 基于关系类型 删除所有关系
# 生成关系匹配器
relation_matcher = RelationshipMatcher(graph) # 生成关系匹配器
# 删除所有couple关系
relations = relation_matcher.match(r_type='COUPLE')  # 可迭代对象
for relation in relations:
    graph.separate(relation)

# 基于节点 删除node1和node2的关系
# 生成关系匹配器
relation_matcher = RelationshipMatcher(graph) # 生成关系匹配器
# 找到 node1 和node2 之间的关系
relations = relation_matcher.match([node1,node2])
# 遍历所有匹配到的关系
for relation in relations:
    graph.separate(relation)

# 删除关系与两端
# graph.delete(关系)
graph.delete(relation2)# 删除relation2这个关系以及相关节点

# -----------------------
# ------    改    --------
# -----------------------

# 修改节点属性值
# 节点[属性名] = 属性值
node1['age']=26
graph.push(node1)# 略

# 修改关系属性值
relation2['strong']=90
graph.push(relation2)# 略

# -----------------------
# ------    查    --------
# -----------------------

# 节点查询
# 根据属性值查询满足条件的节点
# node_matcher = NodeMatcher(graph)# 创建节点匹配器
# node_matcher(节点类型1,节点类型2,属性1=属性值1,属性2=属性值2)# 提取满足属性值的节点
node_matcher = NodeMatcher(graph) # 节点匹配器
a = node_matcher.match('female',age=21) # 在节点类型中,提取满足属性值的节点

# 更具复杂规则的属性值查询满足条件的节点
# nodes = node_matcher.match()
# for node in nodes:
#     规则
node_matcher = NodeMatcher(graph) # 节点匹配器
nodes = node_matcher.match()# 直接提取所有节点(就是没有筛选条件的情况下)
# 进行便利,输出所有满足属性值的节点
for node in nodes:
    # ... 可以多层次筛选复杂的属性值
    if node['weight'] < 50:
        print(node)

# 关系查询
# 根据关系类型和属性查询关系
# relation_matcher = RelationshipMatcher(graph)# 创建关系匹配器
# relations = relation_matcher.match(r_type=关系类型,属性1=属性值1,属性2=属性值2)# 在该关系类型中找到属性值满足条件的关系
relation_matcher = RelationshipMatcher(graph)# 关系匹配器
relations = relation_matcher.match(r_type='KNOW',strong=60)# 匹配结果为字典构成的可迭代

# 根据复杂关系进行匹配
# relation_matcher = RelationshipMatcher(graph)# 创建关系匹配器
# relations = relation_matcher.match()# 找到
# for relation in relations:
#     规则
relation_matcher = RelationshipMatcher(graph)# 创建关系匹配器
relations = relation_matcher.match()# 提取所有关系
for relation in relations:
    # ..可以多层筛选复杂的属性值
    if relation['strong'] > 20:
        print(relation)

# 节点+关系
# graph.match(nides=[节点1,节点2],r_type=关系类型,limit=None)
graph.match(nides=[node1,node3],r_type='KNOW',limit=None)
# 其中limit指的是,匹配关系的最大数量
# param limit: maximum number of relationships to match (:const:`None` means unlimited)

# -----------------------
# ------   案例   --------
# -----------------------

# 常见数据操作案例展示
# --------- 1 ---------
graph = Graph() # 初始化该图
tx = graph.begin() # 开始一个Transaction
node_1 = Node("Person",name="Peter") # 第一个节点是一个名字叫做Peter的人
tx.create(node_1)
tx.push(node_1) # 将其push到服务器
# or
tx.commit()# 将以上更改一次提交

# --------- 2 ---------
# Cypher 语句增加一个外壳
# 运行一个cypher 语句 graph.run('a cypher expression')
result = graph.run('match (p:Paper) return p.title, p.author limit 20')


# cursor 相当于结果一个游标((a cursor is a navigator for a stream of records)
cursor = graph.run() # 返回一个cursor对象,可以使用循环对cursor
# 循环方法1,使用 forward:
while cursor.forward():
    print(cursor.current['name'])

# 循环方法2,使用 for
for record in cursor:
    print(record["name"])

# 将graph run 的结果进行呈现,并可以转为其他格式
graph.run().data() # 基本格式是list of dictionary
graph.run().to_data_frame() # pd.DataFrame
graph.run().to_ndarray() # numpy.ndarray
graph.run().to_subgraph()
graph.run().to_subgraph()
graph.run().to_table()

# --------- 3 ---------
# py2neo创建

a = Node("Person",name="Alice")
b = Node("Person",name="Bob")
r = Relationship(a,"KNOWS",b)
s = a|b|r # 操作符(|)将节点和关系组合到一个子图(Subgraph)对象中,
# 子图对象可以一次性传递给图数据库进行创建。
graph = Graph()
graph.create(s)

# py2neo中慎用merge,可以先做存在判断,然后再用create语句.
# py2neo如果匹配上则用当前实体覆盖数据库中的已有实体(优先覆盖)
# 而不是Cypher中检测标签和属性,如果已存在就不创建(优先不创建)
graph.merge(node_1,"Person","name")       # 根据name属性对person结点进行merge

# 对应Cypher语句
# match (c:course)
# merge (t:teacher {name:c.teacher})
# return c.name,c.teacher

# --------- 3 ---------
# py2neo查询

matcher_1 = NodeMatcher(graph) # 创建节点匹配器
# 让它在year=2017的条件下,标签为paper,ID属性为09076的结果
# node的类型仍然是NodeMatcher对象
node = matcher_1.match("Paper",ID='09076').where(year=2017)

matcher_2 = RelationshipMatcher(graph) # 创建关系匹配器
# relation的类型仍然是RelationshipMatcher对象
relation = matcher_2.match(r_type="Cited").limit(50) # 匹配类型为Cited的关系,最多五十条记录

# 使用这两个模块后返回仍然是NodeMatche对象,将其转换为实体
node_1 = matcher_1.match("Paper",ID='09076').first() # 取第一个匹配到的节点,类型为列表
result_1 = list(node) # 转换为列表
result_2 = list(result)# 类型为列表


# node和relationship也自带匹配属性
graph.nodes.match("Person").first() # 但运行速度更慢

# Cypher的原生匹配,没有限定类型
# match g = (p1:Person) -[r:]->(p2:Paper)
# where p2.year>2008
# return g,p1.name,r.type,p2.title

# --------- 4 ---------
# py2neo.ogm (Object-Graph Mapping),ogm是基于Graphobject的
'''
class Movie(GraphObject):
    __primarylabel__ = 'Movie'# 基础标签 电影
    __primarykey__ = 'title' # key属性 title

    title = Property()  # 影片名
    tag_line = Property('tagline')
    release = Property()  # 发行时间
    restricted = Label()  # 是否限制级

    actors = RelatedFrom("Person", "ACTED_IN")  # 演员关系,与 "Person" 类的 "ACTED_IN" 关系相连
    directors = RelatedFrom("Person", "DIRECTED")  # 导演关系,与 "Person" 类的 "DIRECTED" 关系相连
    producers = RelatedFrom("Person", "PRODUCED")  # 制片人关系,与 "Person" 类的 "PRODUCED" 关系相连

class Person(GraphObject):
    __primarykey__ = "name" #  key属性 name

    name = Property()
    acted_in = RelatedTo(Movie)  # 演员关系,与 "Movie" 类的关系相连

release = Property() # 指定release为属性,则可以赋值
M = Movie()
M.release = 1995

'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/161175
推荐阅读
相关标签
  

闽ICP备14008679号