在Python中使用Neo4j数据库的教程
作者:Nigel 发布时间:2024-01-15 00:40:54
一个快速的REST例子
首先来看些基本知识。如果没有服务API,Neo4j就不能支持其他语言。该接口提供一组基于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端点。在消息载荷中接受传送来的Cyper请求并执行这些查询,在HTTP响应中返回结果。
正是这种REST API接口,使得现在已有的各种Neo4j驱动得以建立。py2neo提供了这些REST资源的简单封装,这使Python应用程序开发者可以放心使用Neo4j而不用考虑底层的客户机-服务器协议。
一个简单的应用
为实际验证py2neo,我们将着眼于建立一个简单的用于存储姓名和电子邮件地址的通讯录管理系统。我们自然会使用节点来模拟每一个独立实体,但它是要记住,Neo4j没有类型的概念。类型是从周围的关系和属性推断来的。
下面的关系图中人显示为红色、电子邮件地址节点显示为蓝色。这些当然是纯粹的逻辑演示节点,但数据本身并没有区别。
我们的应用程序将完成两个功能:添加新的联系人信息和检索联系人的完整列表。为此,我们将创建一个Person类包装Py2neoNodeobject,这使我们有一个底层处理的实现且留出用户级的功能。上图中的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来抽象出大多数沉重的负担。这里的例子并没有解决唯一性,尽管功能上提供了唯一索引和CypherCREATE UNIQUE语句。Django开发者可能也想要考虑一个层,如Neomodel,它在Py2neo顶层上表示了一个Djangoesque ORM-style 层。


猜你喜欢
- 本文介绍了关于redux-saga中take使用方法详解,分享给大家,具体如下:带来一个自己研究好久的API使用方法.redux-saga中
- 主要记录一下:图片验证码1.获取登录界面的图片2.获取验证码位置3.在登录页面截取验证码保存4.调用百度api识别(目前准确率较高的识别图片
- Python是一种面向对象的语言,但它不像C++一样把标准类都封装到库中,而是进行了进一步的封装,语言本身就集成一些类和函数,比如print
- Mac键盘符号和修饰键说明⌘ Command⇧ Shift⌥ Option⌃ Control↩︎ Return/Enter⌫ Delete⌦
- 1 之前我们学习了列表,知道列表可以用来存储一组数据,可以增删改查,可以遍历2 之前我们学习了字典,知道字典可以用来存储键值对,与列表类似,
- 前言Django项目本身就可以启动运行,为什么还需要部署到Apache或者Nginx上呢?初学者都会遇到这个问题,我们来看看官方解释:It&
- 本文分析了CodeIgniter连贯操作的底层原理。分享给大家供大家参考,具体如下:php oop连贯操作原理->符号其实是传递对象指
- 今晚终于解决了串口发送的问题,更改代码如下:def write(self, data): if self.aliv
- 本次案例使用OpenCV和selenium来解决一下滑块验证码先说一下思路:弹出滑块验证码后使用selenium元素截图将验证码整个背景图截
- 本文主要包括三大方面,大家仔细学习。1、导航栏中的表单导航栏中的表单不是使用 Bootstrap 表单 章节中所讲到的默认的 class,它
- 这几天研究UTF-8编码,太晕了,把我的看法和各位讨论讨论。欢迎来批啊。以下都是我的想法,哪里有不对的请不吝赐教,帮忙指出来。相关的题外话:
- 在mysql数据库中,mysql key_buffer_size是对MyISAM表性能影响最大的一个参数(注意该参数对其他类型的表设置无效)
- 本文实例讲述了Python实现的计数排序算法。分享给大家供大家参考,具体如下:计数排序是一种非常快捷的稳定性强的排序方法,时间复杂度O(n+
- 如下所示:import cv2fps = 16 size = (width,height) videowriter = cv2.VideoW
- 最近我在用梯度下降算法绘制神经网络的数据时,遇到了一些算法性能的问题。梯度下降算法的代码如下(伪代码):def gradient_desce
- 这篇文章主要介绍了python imread、newaxis用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
- 创建函数时问题马上出现: ERROR 1418 (HY000): This routine has none of DETERMINISTI
- 前面的python3入门系列基本上也对python入了门,从这章起就开始介绍下python的爬虫教程,拿出来给大家分享;爬虫说的简单,就是去
- KNN核心算法函数,具体内容如下#! /usr/bin/env python3# -*- coding: utf-8 -*-# fileNa
- 最近好多分享这个问题的代码,题目说的是用面向对象或者函数式编程,下面是PYTHON的实现示例#!/usr/bin/python#encodi