用py2neo对Neo4j进行数据的增删改查:节点
主要参考1:官方文档;参考2:Neo4j和py2neo配合使用。
1.连接Neo4j
from py2neo import Graph # 导入 url = 'bolt://localhost:7687' # 本地连接地址 usr = 'neo4j' # 用户名 key = '1' # 密码 graph = Graph(url, auth = (usr, key)) # 连接到的图
2. 节点创建和节点修改
写在前面:使用py2neo对Neo4j进行修改,当我们直接用语法,Node或者Realation时,如果没有进行绑定,就会仅仅是对本地端的数据进行了处理,而没有作用到Neo4j上去,所以,在每一次处理完之后,一定要记得用graph.create或者graph.push将我们的处理传递到Neo4j上去。插入一段官网关于节点创建的描述,进行理解。英中(机翻)对照:
Node objects can either be created implicitly, by returning nodes in a Cypher query such as , or can be created explicitly through the constructor. In the former case, the local Node object is bound to the remote node in the database; in the latter case, the Node object remains unbound until create or merged into a Neo4j database.
CREATE (a) RETURN a
节点对象可以通过Cypher查询中的返回节点(如)进行隐式创建,也可以通过构造器明确创建。在前一种情况下,本地节点对象与数据库中的远程节点绑定:在后一种情况下,节点对象保持未绑定,直到
创建
或合并
到 Neo4j 数据库。
上面说到,如果创建节点,可以通过Cypher进行创建,或者通过构造器,而在使用构造器时,我们的节点对象由于未绑定,在Neo4j端其实是不发生变化的,需要再传递一下。
下面根据我个人学习和实际使用到的情况,逐步说明。
首先是简单的节点操作。
2.1 创建一个新的节点
创建节点主要用Node函数,格式为 my_node = Node("label", name = 'XXX')。“label” 可以是我们给节点的一个分类,比如 “人物”,“地点”。最好是一个大类,这在我们检索时,可以先确定,这个节点 “label” 是什么,之后再考虑填了什么内容。name 是一个属性,属性值就是里面的 “XXX”,在我们的浏览器图示中节点展示的一般是 name 的属性值。我们也可以加其他属性和属性值,key-value 对,格式和name = "XXX",一样,逗号连接。同样我们也可以给节点加多个标签,直接在已有的 “label” 后面增加即可,逗号连接。
不要忘记用 create 把我们本地端的变化传递到连接的 Neo4j 上。graph.create() 用在创建时的连接。后面我们还会用到 create.push() 对已有节点或者关系的改动进行传递。
from py2neo import Graph, Node url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) a = Node('判决文书', name = 'XXX刑事判决书') # 创建一个label = '判决文书',属性name值为',此时节点并没有真的传到Neo4j graph.create(a) # 将节点 a 创建到数据库
下图左是我们运行上面代码后在浏览器查询的结果,可以看到,节点显示的是属性name的值,并且有一个id,这个id是该节点的唯一标识。如果再运行一次代码,就会创建一个内容一模一样的节点,而 id 是不一样的。这里就能发现一个问题,在创建节点时,create并不会自己检查该节点是否已经创建,所以在实际使用,应先检查要创建的节点是否存在。下图右是查看的数据,可以看到labels为‘判决文书’,在左图为黄色表示,这里称为类别。name和值包含在properties属性里,数据格式是像字典形式的。
2.2 查询符合某条件的节点,不存在,则创建该节点
上面说到,Node 只管创建,有点像通信里的 “透明” 传输,它不会去看里面的内容是什么、是否一样。这里就用查找函数帮我们看里面的内容,并进行筛选。由于我安装的是最新稳定版的py2neo,所以语法上可能和其他 blog 里写的略有区别。导入的是 matching 里的函数,有NodeMatcher,NodeMatch,用于节点的匹配,有RelationshipMatcher,RelationshipMatch,用于关系的匹配。此外,还可以直接通过 graph.match() 进行匹配,graph.match() 内部其实也是调用 Nodematcher 和 RelationshipMatcher 来实现的。
下面是关于节点的匹配。我们先创建一个节点匹配器 matcher 然后通过 matcher.match() 内部加入条件,对范围进行确认,后缀 .exists() 是看该节点或该类节点是否存在,存在返回 bool 值True,否则返回 bool 值 False。.first() 是返回符合条件的一个节点。类型就是 Node。这里用了两种方式进行条件的指定,一种是直接 match() 里写,一种是利用 .where() 。where() 支持比较复杂的形式。
from py2neo import Graph, Node from py2neo.matching import * url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) matcher = NodeMatcher(graph) # 创建节点匹配器 result = matcher.match('判决文书', name = 'XXX刑事判决书').exists() # 符合条件的是否存在 print('节点是否存在:') print(result) if result == False: node = Node('判决文书', name = 'XXX刑事判决书') graph.create(node) else: node = matcher.match('判决文书').where(name = 'XXX刑事判决书').first() # 评估匹配并返回匹配的第一个节点 print('node') print(node) # 说明 # exist() 如果存在至少一个符合条件的节点,则返回True,否则返回False # 上面写了两种匹配方式,一种是直接在match里指定特点,一种是用where进行匹配,where可以进行精确匹配,可以用表达式进行较复杂的匹配
2.3 对已有节点进行标签增加和属性增改
用 node.add_label() 给节点增加标签。用 node[“某属性”] = “属性值” 进行对节点进行 key-value 对的增加,很像字典的操作。此外,还有 node.setdefault("某属性",default = “属性值”) ,这个说明在代码注释中。
需要注意的是,上述修改完成后,一定要用 graph.push() 把变动传递到 Neo4j 上。
from py2neo import Graph, Node from py2neo.matching import * url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) matcher = NodeMatcher(graph) # 创建节点匹配器 node = matcher.match('判决文书').where(name = 'XXX刑事判决书').first() # 评估匹配并返回匹配的第一个节点 node.setdefault('审判程序', default = '刑事二审') # setdefault() 如果此节点具有的属性value,则返回其值。如果没有,添加‘审批程序’属性和对应的属性值 node.add_label('案件') node['案号'] = '001' # 添加“案号”属性对应的属性值为“001” print('node:') print(node) graph.push(node) # 将更改push到图中 print('node:') print(node) # 说明:这里同样写了两种增添方式,具体使用根据情况。可以看出第二种方式类似字典的形式的
其他函数:
移除标签:node.remove_label(label)
2.4 获取节点id和根据id查找节点
用 node.identity 获取节点的 id ,用节点匹配器直接查找id = xxx 的节点。
from py2neo import Graph, Node from py2neo.matching import * url = 'bolt://localhost:7687' key = '1' usr = 'neo4j' graph = Graph(url, auth = (usr, key)) matcher = NodeMatcher(graph) # 创建节点匹配器 # 先创建一个节点 node = Node('人', name = '张三') graph.create(node) print(node) # 获取该节点的id node_id = node.identity print(node_id) # 根据 id 查找节点 created_node = matcher[node_id] print(created_node) # 删除节点 graph.delete(created_node) # graph.separate(created_node)
2.5 删除节点
这一部分和创建类似,用graph.delete(node)即可。需要注意的这个节点也必须是我们已经从远程匹配到的节点。graph.separate()也可以。delete可以传递的参数:节点,关系,图和子图。
为了控制篇幅,其他内容将在下节进行记录。