py2neo 使用教程

Py2neo是Neo4j数据库的python驱动

官方支持的版本

  • Python 2.7 / 3.3 / 3.4 / 3.5
  • Neo4j 2.0 / 2.1 / 2.2 / 2.3 / 3.0

安装

我使用的版本是python 3.7, neo4j 3.4,目前没有问题
这里是py2neo v4 handbook
安装,它会自动安装依赖包neo4j(就是官方建议的那个包)

pip3 install py2neo

链接

默认的端口号就是7474,最新的链接方式是传入用户名和密码的元组

from py2neo import Graph,Node,Relationship
graph = Graph("http://localhost:7474",auth=("neo4j","password"))

创建节点Node和关系Relationship

a = Node("Person", name="Alice")
b = Node("Person", name="Bob")
ab = Relationship(a, "KNOWS", b)
graph.create(ab)

Node和Relationship可以定义对应的实例,Node第一个参数是label, 再利用graph.create()创建

数据对象 Object

Node

node是保存在Neo4j里面的数据储存单元,在创建好node后,我们可以有很多操作,比如

#获取key对应的property
x=node[key] 
 #设置key键对应的value,如果value是None就移除这个property
node[key] = value
 #也可以专门删除某个property
del node[key]
#返回node里面property的个数
len(node)
#返回所以和这个节点有关的label
labels=node.labels
#删除某个label
node.labels.remove(labelname)
#将node的所有property以dictionary的形式返回
dict(node)

Relationship

对于relationship,也有很多相似的操作,这里只列举几个

#创建Relationship
Relationship`(*start_node*, *type*, *end_node*, ***properties*)
#返回Relationship的property
Relationship[key]
#删除某个property
del Relationship[key]
#将relationship的所有property以dictionary的形式返回
dict(relationship)

PropertyDict:因为Node和Relationship在这个驱动中都继承了PropertyDict这个类,而这个类继承类python里面的dict,所以操作和python本身的dict一模一样

Subgraphs

子图是节点和关系不可变的集合,我们可以通过set operator来结合,参数可以是独立的node或relationships

subgraph | other | ...      结合这些subgraphs
subgraph & other & ...   相交这些subgraphs
subgraph - other - ...     不同关系
#比如我们前面创建的ab关系
s = ab | ac

查询 Query

最新的v4版本中,对node的查询,已经移除原有的find(),可以在nodes中调用match来找点

graph.nodes.match(self, *labels, **properties): 找到所有的nodes,

或者使用 py2neo.matching包里面的NodeMatcher(graph) 函数构建个matcher再查询(其实上面的方法就调用的这个东西), 首先创建Matcher来执行查询,它会返回一个Match类型的数据,可以继续使用where(),first(),order_by等操作,可以用list强制转换

graph = Graph()
matcher = NodeMatcher(graph)
matcher.match("Person", name="Keanu Reeves").first()
#结果 (_224:Person {born:1964,name:"Keanu Reeves"})

# where里面使用_指向当前node
list(matcher.match("Person").where("_.name =~ 'K.*'"))

如果要查询relationship,直接在graph里面调

graph.match(nodes=None, r_type=None, limit=None) 找到所有的relationships

更新 Update

更新先要找出Nodes,再使用事务的push更新

from py2neo import Graph, NodeMatcher, Subgraph

tx = graph.begin()
# 找到你要找的Nodes
matcher = NodeMatcher(graph)
nodes = matcher.match("User")
# 将返回的“Match”类转成list
new_nodes = list(nodes)
## 添加你要修改的东西
for node in new_nodes:
    node['tag'] = node['tag'].split(',')
# 里面是Node的list可以作为Subgraph的参数
sub = Subgraph(nodes=new_nodes)
# 调用push更新
tx.push(sub)
tx.commit()

批处理:

对于大量的插入一般是很费时的,首先我们可以使用事务,加快一定速度,而插入的方法一样重要,我们很多时候是遍历一个文件然后生成图,例子中我们生成每个Node后,先把他们放入一个List中,再变为Subgraph实例,然后再create(),耗时比一条条插入至少快10倍以上

tx = graph.begin()
nodes=[]
for line in lineLists:
    oneNode = Node()
    ........
    #这里的循环,一般是把文件的数据存入node中
    nodes.append(oneNode)
nodes=neo.Subgraph(nodes)
tx.create(nodes)
tx.commit()

前面我们说了关系的创建,如果在node存进去后,再通过py2neo层面的“查找node,create关系”这样的效率是很低的,时间主要花在通过"reference Id"去一个个去查找对应的node,然后再和这个node建立关系,这里强烈推荐使用原生语句,效率不是一般的高

#假定我们已经把两种node存进去了,label分别是Post和User,现在需要在他们间建立某关系
graph.run("MATCH (p:Post),(u:User) \
                WHERE p.OwnerUserId = u.Id \
                CREATE (u)-[:Own]->(p)")

推荐阅读更多精彩内容