用py2neo对Neo4j进行数据的增删改查:关系

  这里接着上一篇的内容,进行关系的创建和关系的查找。

关系的创建和查找

1 创建两个节点间的关系

  创建关系时用函数 Relationship() 函数。格式为relation = Relationship(start_node, relationship, end_node) 。start_node为开始节点,end_node为结束节点,relationship 为两节点间的关系。需要知道的是,Neo4j 的关系都是有向的,这里的关系词是由start_node 指向 end_node 的关系。创建后,通过graph.create(relation) 导入Neo4j。

from py2neo import Graph, Node, Relationship
from py2neo.matching import *

url = 'bolt://localhost:7687'
key = '1'
usr = 'neo4j'

graph = Graph(url, auth = (usr, key))
node_matcher = NodeMatcher(graph)

case = node_matcher.match('判决文书', name = 'XXX刑事判决书').first()    # 获得name为XXX刑事判决文书的“判决文书”类 节点
people = node_matcher.match('被告人','', name = 'XXX').first()  # 获得name为“XXX”的“被告人”类节点  
relation = Relationship(case, '被告人', people)    # 创建判决文书和被告人间的关系,关系词为“被告人”
graph.create(relation)    # 将创建传递到图上

  如果创建新的节点和对应的关系怎么办,很简单,先创建节点,再创建关系(注意哦,这个和后续可能的删除顺序是相反的),比如下面示例。我们就不用查询已有节点的,直接将创建的节点用Relationship 连接就好了。但是可能 create 需要逐步来。我自己尝试的时候是不能批量 create 的,如果是需要批量创建节点,建议直接查询 Neo4j 批量创建节点寻找方法,Neo4j 是提供多种批量导入方式的。

2  查找以某种关系直接连接的两个节点

   前面在查询节点时,用到的是NodeMatcher。在查询关系时会类似用到RelationshipMatcher,下面直接给出查询两者有直接相连关系的例子。并把我遇到问题进行总结。希望对大家也有所帮助。

  首先,来看relation_matcher() 函数的格式。relation_matcher({start-node, end-node}, r_type = XXX, key = value)。这里有三组参数,第一组在 {} 里是起始节点和终止节点,对节点做出限制,可以是None;第二组是关系类型 r_type,第三组是键值组合。这些都可以用在关系查找中,对我们的关系进行限制。在下面例子中,可以看到,relation_matcher() 后面也可以接如.first() 等函数进行补充,比如.where() 用表达式对关系进行限制,用.limit() 限制查找的数量,还有之前出现多次的.exists() 确定是否存在。

  接着,来说一说我遇到的问题:

  1)能不能查询比较深度的关系,必须直接相连吗,之间隔着一个节点可以吗?我的尝试是不能。如果有朋友尝试出了可以分享一下。

  2)在我使用该函数的例子中,如果节点确实存在,确实存在直接的连接关系,是可以正确查询的。

  3)使用graph.match() 传同样的参数,是可以替代relation_matcher.match() 的

  4)如果我们在 node_matcher.match 部分查找到的其中一个节点结果为空,即这个节点不存在,就会传入空节点。这样会查询另外一个节点(认为这个节点不空)所以与之直接相连符合条件的结果。

from py2neo import Graph, Node, Relationship
from py2neo.matching import *

url = 'bolt://localhost:7687'
key = '1'
usr = 'neo4j'

graph = Graph(url, auth = (usr, key))
node_matcher = NodeMatcher(graph)        # 节点匹配器
relation_matcher = RelationshipMatcher(graph)    # 关系匹配器

# 要被查询关系的两个节点,注意,这里不能时自己直接node一个再去匹配的,对于匹配来说,只有连接的graph中存在的节点,才可以被读入。所以我们先要获取一下。内容有重复的节点,不影响
first_node = node_matcher.match('', name = '张三').first()    
second_node = node_matcher.match('职业', name = '法外狂徒').first()        

result = relation_matcher.match({first_node, second_node}, r_type = None, key = value).first()    # 查询结果的格式我们是不能直接读的,可以用.first(),或者对结果list,即list(result)  
print(result)      # 打印结果,格式一般是 (节点一)-[关系]->(节点二)
print(result.nodes) # 打印节点
graph.separate(relation)    # 删除关系
# graph.delete(relation)    # 删除关系

 3 关系的删除

  单独删除关系用函数graph.separate(relationship)。当我们需要删除大图中的一部分节点时,需要先删除关系再删除节点,这时候就会用到这个函数。具体使用在上面的代码中已经实现。separate可以传的参数有关系、节点、图和子图。delete同样

posted @ 2021-10-19 20:29  piukaty  阅读(1463)  评论(0编辑  收藏  举报