在Python中使用Neo4j的方法
本文介绍如何在Python中通过py2neo库连接Neo4j图数据库。内容涵盖REST API基础、使用GraphDatabaseService创建节点与关系,以及构建简单的通讯录管理系统示例。旨在帮助开发者快速上手Neo4j在Python环境中的实际应用,无需深入底层协议细节。
Neo4j与Python集成概述
Neo4j是一个基于Java的对象导向数据存储,设计为可直接嵌入应用程序中。随着社区的发展,它逐渐支持了包括.NET、Ruby、Python、Node.js及PHP在内的多种语言和平台,拥有广泛的技术支持基础。因此,在任何项目中引入Neo4j都是可行的选择。
本文将重点介绍Python语言,尽管其哲学与Java有显著差异,但通过展示py2neo库的使用,可以构建出简单的应用程序。
一个快速的REST例子
通过REST API访问Neo4j
首先了解基础知识。Neo4j通过服务API支持其他语言,该接口提供了一组基于JSON消息格式的RESTful Web服务以及全面的发现机制。使用cURL是访问此接口最快且最简单的方法:
$ curl http://localhost:7474/db/data/
{
"extensions" : {
},
"node" : "http://localhost:7474/db/data/node",
"node_index" : "http://localhost:7474/db/data/index/node",
"relationship_index" : "http://localhost:7474/db/data/index/relationship",
"extensions_info" : "http://localhost:7474/db/data/ext",
"relationship_types" : "http://localhost:7474/db/data/relationship/types",
"batch" : "http://localhost:7474/db/data/batch",
"cypher" : "http://localhost:7474/db/data/cypher",
"transaction" : "http://localhost:7474/db/data/transaction",
"neo4j_version" : "2.0.0-M03"
}
从该端点返回的JSON对象包含一组资源名称和URI,指向Cypher端点。消息载荷接受传入的Cypher请求并执行查询,结果通过HTTP响应返回。
正是这种REST API接口,使得现有的各种Neo4j驱动得以建立。py2neo提供了对这些REST资源的简单封装,使Python应用程序开发者能够无需考虑底层客户端-服务器协议即可使用Neo4j。
使用py2neo构建简单应用
一个简单的应用
为了验证py2neo,我们将建立一个简单的通讯录管理系统,用于存储姓名和电子邮件地址。我们使用节点来模拟每个独立实体,但需注意Neo4j没有类型的概念,类型是从周围的关系和属性推断出来的。
在下面的关系图中,人显示为红色,电子邮件地址节点显示为蓝色。这些是纯粹的逻辑演示节点,数据本身没有区别。

我们的应用程序将完成两个功能:添加新的联系人信息和检索联系人的完整列表。为此,我们将创建一个Person类来包装Py2neoNode对象,这使我们有一个底层处理的实现且留出用户级的功能。上图中的ROOT节点是指上图中一个固定的参考点,我们沿着这个点开始。
让我们直接看看代码。下面是一个完整的小型应用。这个程序允许添加新的名字与一个或者更多email地址相连接的以及提供了一个容易的方式来显示这些连接信息的一个命令行工具。没有参数的运行是显示使用模式,而且这个唯一的依赖只是需要一个本地未修改的Neo4j实例(instance)而已。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from
__future__
import
print_function
import
sys
from
py2neo
import
neo4j,
node,
rel
graph_db
=
neo4j.GraphDatabaseService()
class
Person(object):
_root
=
graph_db.get_or_create_indexed_node("reference",
"contacts",
"root")
@classmethod
def
create(cls,
name,
*emails):
person_node,
_
=
graph_db.create(node(name=name),
rel(cls._root,
"PERSON",
0))
for
email
in
emails:
graph_db.create(node(email=email),
rel(cls._root,
"EMAIL",
0),
rel(person_node,
"EMAIL",
0))
return
Person(person_node)
@classmethod
def
get_all(cls):
return
[Person(person.end_node)
for
person
in
cls._root.match("PERSON")]
def
__init__(self,
node):
self._node
=
node
def
__str__(self):
return
self.name
+
"\n"
+
"\n".join(" <{0}>"
.format(email)
for
email
in
self.emails)
@property
def
name(self):
return
self._node["name"]
@property
def
emails(self):
return
[rel.end_node["email"]
for
rel
in
self._node.match("EMAIL")]
if
__name__
==
"__main__":
if
len(sys.argv)
<
2:
app
=
sys.argv[0]
print("Usage:
{0} add <name> <email>
[<email>...]".format(app))
print("
{0} list".format(app))
sys.exit()
method
=
sys.argv[1]
if
method
==
"add":
print(Person.create(*sys.argv[2:]))
elif
method
==
"list":
for
person
in
Person.get_all():
print(person)
else:
print("Unknown
command")
在第09行上是第一行Py2neo代码,用来创建了一个GraphDatabaseService对象。通过这个,我们就可以访问使用Neo4j server的大多数功能。可选一个URI传递到这个构造器里,尽管如果什么都没有提供,代而取之的是使用默认的本地参数。也就是说下面两行是完全相等的:
graph_db
=
neo4j.GraphDatabaseService()
graph_db
=
neo4j.GraphDatabaseService
(http://localhost:7474/db/data/)
第13行介绍了调用了get_or_create_indexed_node,它提供一种在图形里创建固定引用点的漂亮方式。传统的Neo4j索引允许节点和关系通过键值对访问,而在这个代码里我们使用了带连接的关键字和root值的引用索引实例。在第一次执行时,会创建一个新的节点,而且在随后的执行中,这个节点(即root)会复用(reused)。
在第17行,我们看见了推荐的节点和关系抽象的标记,以及接受和使用节点和关系抽象的create方法。任意多的抽象都可以被传递到这个方法中,并且在单个批处理转换中创建实体并以指定它们的顺序作为一个列表返回。抽象节点用节点函数表示并带有一些属性,然而抽象关系使用rel函数接受一个起始节点,类型和终止节点。上下文中,其他节点,关系起始和终止节点可能整合引用到在其他批处理中其他节点。在我们的例子中,我们把根节点连接到新创建的person节点,否则就作为项目0(item 0)了。
这次我们在第24行和38行上以match方法形式和关系见面[@Lesus 注: oschina代码行数有问题。对应于本文的第28和44行]。它试图使用一个特殊的条件集合(set)标识关系,然后使用列表(list)返回它们。这这些示例中,这个关系和PERSON关系相匹配,从root节点和EMAIL关系开始到所给定的person节点。和Cypher很相似,用来查询包含MATCH关键字的场景。
最后值得注意的一点是在上面的代码中访问节点属性的方式只是其中一种简单的方式。Py2neo重写了标准python的__getitem__和 __setitem__方法,通过方括号标识来方便访问任何属性。这点在第34和38行上可以看到。[@Lesus 注:对应于本文的第39和44行]
应用小结与扩展建议
小结
在那里(代码行34和38)我们这样做了,这显示了它是如何快速简易地在JAVA环境之外拼凑出一个Neo4j应用程序,也显示了Py2neo是如何通过REST API来抽象出大多数沉重的负担。这里的例子并没有解决唯一性,尽管功能上提供了唯一索引和Cypher CREATE UNIQUE语句。Django开发者可能也想要考虑一个层,如Neomodel,它在Py2neo顶层上表示了一个Djangoesque ORM-style 层。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对本站的支持。如果你想了解更多相关内容请查看下面相关链接
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













