在Python中使用Neo4j数据库的教程


Posted in Python onApril 16, 2015

 一个快速的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没有类型的概念。类型是从周围的关系和属性推断来的。

下面的关系图中人显示为红色、电子邮件地址节点显示为蓝色。这些当然是纯粹的逻辑演示节点,但数据本身并没有区别。 

在Python中使用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 层。

Python 相关文章推荐
python获取当前时间对应unix时间戳的方法
May 15 Python
详解Django之admin组件的使用和源码剖析
May 04 Python
python中利用h5py模块读取h5文件中的主键方法
Jun 05 Python
django 将model转换为字典的方法示例
Oct 16 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
Jan 15 Python
Django框架使用内置方法实现登录功能详解
Jun 12 Python
详解pytorch 0.4.0迁移指南
Jun 16 Python
python中class的定义及使用教程
Sep 18 Python
python使用pip安装SciPy、SymPy、matplotlib教程
Nov 20 Python
pytorch制作自己的LMDB数据操作示例
Dec 18 Python
python3连接MySQL8.0的两种方式
Feb 17 Python
python3 实现mysql数据库连接池的示例代码
Apr 17 Python
使用Python的Zato发送AMQP消息的教程
Apr 16 #Python
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
Apr 16 #Python
使用Python编写一个简单的tic-tac-toe游戏的教程
Apr 16 #Python
Python基于scrapy采集数据时使用代理服务器的方法
Apr 16 #Python
在Python的gevent框架下执行异步的Solr查询的教程
Apr 16 #Python
使用Python的Treq on Twisted来进行HTTP压力测试
Apr 16 #Python
Python3中多线程编程的队列运作示例
Apr 16 #Python
You might like
PHP 解决utf-8和gb2312编码转换问题
2010/03/18 PHP
yii框架表单模型使用及以数组形式提交表单数据示例
2014/04/30 PHP
PHP用mb_string函数库处理与windows相关中文字符及Win环境下开启PHP Mb_String方法
2015/11/11 PHP
PHP结合Jquery和ajax实现瀑布流特效
2016/01/07 PHP
漂亮的thinkphp 跳转页封装示例
2019/10/16 PHP
Laravel 框架控制器 Controller原理与用法实例分析
2020/04/14 PHP
Swoole源码中如何查询Websocket的连接问题详解
2020/08/30 PHP
asp.net HttpHandler实现图片防盗链
2009/11/09 Javascript
JQuery+JS实现仿百度搜索结果中关键字变色效果
2011/08/02 Javascript
通过JS获取用户本地图片路径并显示的代码
2012/02/16 Javascript
Js获取数组最大和最小值示例代码
2013/10/29 Javascript
javascript实现的DES加密示例
2013/10/30 Javascript
移动设备web开发首选框架:zeptojs介绍
2015/01/29 Javascript
JavaScript与HTML的结合方法详解
2015/11/23 Javascript
jq checkbox 的全选并ajax传参的实例
2017/04/01 Javascript
微信小程序实现多选框全选与取消全选功能示例
2019/05/14 Javascript
Vue单页面应用中实现Markdown渲染
2021/02/14 Vue.js
[01:38]DOTA2辉夜杯 欢乐的观众现场采访
2015/12/26 DOTA
python调用java的Webservice示例
2014/03/10 Python
python PIL模块与随机生成中文验证码
2016/02/27 Python
Pycharm编辑器技巧之自动导入模块详解
2017/07/18 Python
Python登录并获取CSDN博客所有文章列表代码实例
2017/12/28 Python
Python生成rsa密钥对操作示例
2019/04/26 Python
Django 解决distinct无法去除重复数据的问题
2020/05/20 Python
Python如何绘制日历图和热力图
2020/08/07 Python
Tory Burch英国官方网站:美国时尚生活品牌
2017/12/06 全球购物
伯克斯奥特莱斯:Burkes Outlet
2019/03/30 全球购物
俄罗斯最大的在线手表商店:Bestwatch.ru
2020/01/11 全球购物
strlen的几种不同实现方法
2013/05/31 面试题
环境卫生标语
2014/06/09 职场文书
幼儿园辞职信
2015/05/13 职场文书
《富饶的西沙群岛》教学反思
2016/02/16 职场文书
《狼牙山五壮士》教学反思
2016/02/17 职场文书
Python基础之教你怎么在M1系统上使用pandas
2021/05/08 Python
Redis高级数据类型Hyperloglog、Bitmap的使用
2021/05/24 Redis
Java线程的6种状态与生命周期
2022/05/11 Java/Android