在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中处理字符串之endswith()方法的使用简介
May 18 Python
unittest+coverage单元测试代码覆盖操作实例详解
Apr 04 Python
python 2.7.14安装图文教程
Apr 08 Python
pycharm创建一个python包方法图解
Apr 10 Python
django 中的聚合函数,分组函数,F 查询,Q查询
Jul 25 Python
使用selenium和pyquery爬取京东商品列表过程解析
Aug 15 Python
Python中bisect的使用方法
Dec 31 Python
解决json中ensure_ascii=False的问题
Apr 03 Python
python如何进入交互模式
Jul 06 Python
如何使用Python对NetCDF数据做空间相关分析
Apr 21 Python
Python识别花卉种类鉴定网络热门植物并自动整理分类
Apr 08 Python
python可视化分析绘制带趋势线的散点图和边缘直方图
Jun 25 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
linux iconv方法的使用
2011/10/01 PHP
php中header跳转使用include包含解决参数丢失问题
2015/05/08 PHP
解析WordPress中的post_class与get_post_class函数
2016/01/04 PHP
ExtJS 2.0 实用简明教程之布局概述
2009/04/29 Javascript
一个分享按钮的插件使用介绍(可扩展,内附开发制作流程)
2011/09/19 Javascript
JS 修改URL参数(实现代码)
2013/07/08 Javascript
自己编写的类似JS的trim方法
2013/10/09 Javascript
JS定时器实例详细分析
2013/10/11 Javascript
Angular2从搭建环境到开发步骤详解
2016/10/17 Javascript
js实现移动端导航点击自动滑动效果
2017/07/18 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
jQuery无冲突模式详解
2019/01/17 jQuery
微信小程序云开发实现增删改查功能
2019/05/17 Javascript
js实现的在本地预览图片功能示例
2019/11/09 Javascript
微信小程序按顺序同步执行的两种方式
2019/12/20 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
vue中封装axios并实现api接口的统一管理
2020/12/25 Vue.js
微信小程序自定义胶囊样式
2020/12/27 Javascript
[06:25]第二届DOTA2亚洲邀请赛主赛事第二天比赛集锦.mp4
2017/04/03 DOTA
Python json模块使用实例
2015/04/11 Python
详解Python中__str__和__repr__方法的区别
2015/04/17 Python
对sklearn的使用之数据集的拆分与训练详解(python3.6)
2018/12/14 Python
eclipse创建python项目步骤详解
2019/05/10 Python
使用Python轻松完成垃圾分类(基于图像识别)
2019/07/09 Python
Ibatis如何使用动态表名
2015/07/12 面试题
电子商务专业个人的自我评价
2013/11/19 职场文书
大学四年个人的自我评价
2014/02/26 职场文书
爱国演讲稿500字
2014/05/04 职场文书
三八红旗手先进事迹材料
2014/05/13 职场文书
董事长秘书岗位职责
2015/02/13 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
社区党员干部承诺书
2015/05/04 职场文书
代理词怎么写
2015/05/25 职场文书
2015大学迎新标语
2015/07/16 职场文书
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
2021/08/02 MySQL
分享mysql的current_timestamp小坑及解决
2021/11/27 MySQL