py2neo3.0 批处理方案

py2neo 批处理方案

neo4j是是一个高性能的NOSQL图形数据库,它将结构化的数据存储在网络上而不是表中。它是一个嵌入式的,基于磁盘的、具备完备的事务特性的JAVA持续化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。neo4j 建立数据库有多种方式:

  • cypher
  • load csv
  • REST API

第一种方式不适合批量导入,第二种需要前期的处理,因为比较喜欢python ,所以选择Python的方式,但在baidu,google上看了很多关于批量导入的博客,往往是坑肉少,document上也没有现成的实例,遂决定自己研究py2neo的源码。

1.问题描述

  • 官方实例
from py2neo  import Node,Relationship,Graph
graph=Graph(user="neo4j",password="123456")
a = Node("Person", name="Alice")
b = Node("Person", name="Bob")
ab = Relationship(a, "KNOWS", b)
graph.create(ab)

这样导入的话适合少量的数据,如果数据量上百万,这样就会很慢,因为没建立一个关系,就要向数据库发送一次请求。
- 坑点1
py2neo 中给出Batch类但是没有给出详细具体实例,可能才疏学浅,没搞成

  • 坑点2
    网上批量导入的博文不少,但是大部分是针对Py2neo v2 or v1 ,所以并不能用(有人说怎么不强敌py2neo的版本就可以了,so sorry 不喜欢走回头路)

2.解决思路

批量导入的思想无非就是生成cypher语句就想sql一样,然后一起运行,但是大批量数据,首先必须建立唯一标识不然的就会重复建立。所以按照这个思想,去看源码。

3.实现代码

from py2neo.types import  Subgraph
from py2neo  import Node,Relationship,Graph
graph=Graph(user="neo4j",password="123456")
nodes={"a":Node("person",name="weiyudang",age=13),"b":Node("person",name="wangjiaqi")}
rel_a=Relationship(nodes.get("a"),"likes",nodes.get("b"))
rel_b=Relationship(nodes.get("b"),"likes",nodes.get("a"))
A=Subgraph(relationships=[rel_a,rel_b])   
graph.create(A)
  • 创建节点字典 {Nodoindex:Node(“Person”,name=”weiyudang”)}
  • 创建关系列表 [Relationship(),Relationship()]
  • 建立Subgraph列表,如10000个relationship 为一个subgraph
  • 对Subgraph列表使用多线程multiprosesses
from itertools  import  tee,chain
tee(iterable, n=2) --> tuple of n independent iterators.
chain(*iterables)  --> chain object
    Return a chain object whose .next() method returns elements from the
    first iterable until it is exhausted, then elements from the next
    iterable, until all of the iterables are exhausted.

误区:必须首先将Node节点在内存中拥有唯一的标识,之后在建立关系,否则的话就会重复建立,如下面代码

rel_a=Relationship(Node("person",name="weiyudang",age=13),"likes",Node("person",name="wangjiaqi"))
rel_b=Relationship(Node("person",name="wangjiaqi"),"likes",Node("person",name="weiyudang",age=13))

附:itertools介绍

Functional tools for creating and using iterators.

Infinite iterators:
count([n]) --> n, n+1, n+2, ...
cycle(p) --> p0, p1, ... plast, p0, p1, ...
repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times

Iterators terminating on the shortest input sequence:
chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... 
compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...
dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails
groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)
ifilter(pred, seq) --> elements of seq where pred(elem) is True
ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False
islice(seq, [start,] stop [, step]) --> elements from
       seq[start:stop:step]
imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...
starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...
tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n
takewhile(pred, seq) --> seq[0], seq[1], until pred fails
izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... 
izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... 

Combinatoric generators:
product(p, q, ... [repeat=1]) --> cartesian product
permutations(p[, r])
combinations(p, r)
combinations_with_replacement(p, r)

你可能感兴趣的:(python,数据分析)