摘要
利用py2neo包,实现把excel表里面的数据,插入到neo4j 图数据库中;
- 创建新(节点或关系)到neo4j图数据库中;
- 能够获取neo4j 中已有的(节点或关系),不再创建新(节点或关系);
前置
安装py2neo: pip install py2neo
安装neo4j软件,请自行安装
NodeMatcher & RelationshipMatcher
代码由 Jupyter 编写,建议使用vscode
from py2neo import Graph, Node, NodeMatcher, RelationshipMatcher
import pandas as pd
# 连接到Neo4j数据库
graph = Graph("bolt://localhost:7687", auth=("neo4j", "你设置的密码"))
node_matcher = NodeMatcher(graph)
relationship_matcher = RelationshipMatcher(graph)
TODO: 设置neo4j 远程连接
创建节点
node = Node("Person", name="Alice", age=18)
graph.create(node)
查询获取节点
# 拿到匹配到的第一个节点
node_matcher.match('Person', name='Alice').first()
# 拿到可匹配到的所有
node_matcher.match('Person', name='Alice').all()
节点有则查询,无则创建
def get_node(class_, **kwargs):
if node := node_matcher.match(class_, **kwargs):
# 节点存在,则获取
return node.first()
else:
# 节点不存在,则创建
node = Node(class_, **kwargs)
graph.create(node)
return node
创建关系
Alice - Friend -> Bob
node1 = get_node('Person', name='Alice', age=21)
node2 = get_node('Person', name='Bob', age=20)
graph.create(
Relationship(node1, 'Friend', node2)
)
查询关系
查询 node1 和 node2 之间是否有 Friend 关系
node1 = get_node('Person', name='Alice', age=21)
node2 = get_node('Person', name='Bob', age=20)
relationship_matcher.match(
[node1, node2],
r_type='Friend'
).first()
关系有则查询,无则创建
def get_relation(node1, node2, r_type):
if r := relationship_matcher.match(
[node1, node2],
r_type=r_type
):
return r.first()
else:
r = Relationship(node1, r_type, node2)
graph.create(r)
return r
# 查询已有关系
get_relation(node1, node2, 'Friend')
# 创建新关系
get_relation(node1, node2, 'Classmate')
Cypher语句
虽然 在 NodeMatcher & RelationshipMatcher 介绍的接口已经能够满足大部分情况的使用,本文仍想提供一种使用cypher语句的插入数据到neo4j图数据库的思路。
创建节点
graph.run(
"create (n:Person {name:'js'}) return n"
)
graph.run(
"MERGE (n:Person {name: $name}) \
ON CREATE SET n.created_at = timestamp() \
return n",
name='Cyder'
)
封装类
上述内容的使用还是有所不便,故提供Neo4jDriver
分装类,简化用户操作。
from py2neo import Graph, Node, NodeMatcher, RelationshipMatcher, Relationship
# 连接到Neo4j数据库
class Neo4jDriver:
def __init__(self, url, username, password):
self.graph = Graph(url, auth=(username, password))
self.node_matcher = NodeMatcher(self.graph)
self.relationship_matcher = RelationshipMatcher(self.graph)
def query_node(self, class_, **kwargs):
if node := self.node_matcher.match(class_, **kwargs):
# 节点存在,则获取
return node.first()
def create_node(self, class_, **kwargs):
"""
不创建重复节点
"""
# 节点存在,则获取
if node := self.query_node(class_, **kwargs):
return node
# 节点不存在,则创建
node = Node(class_, **kwargs)
self.graph.create(node)
return node
def query_relationship(self, start_node, rel, end_node):
r = self.relationship_matcher.match(
[start_node, end_node],
r_type=rel
)
return r.first()
def create_relationship(self, start_node, rel, end_node):
if r := self.query_relationship(start_node, rel, end_node):
return r
self.graph.create(
Relationship(start_node, rel, end_node)
)
封装类的使用如下:
# 使用自己的url, username, password,我使用自定义的private起到保密作用
from private import url, username, password
driver = Neo4jDriver(url, username, password)
# 创建节点
data = {
"name": "Jie",
"age": 18
}
node1 = driver.create_node('Person', **data)
print(node1)
# 查询节点
node2 = driver.query_node('Person', name='Jie')
print(node2)
# 查询到节点后,修改节点,再保存到neo4j
node2.update({'age':18})
driver.graph.push(node2)