写在最前面:
在使用知乎的过程中,看到很多大佬们分享的文章,让我受益匪浅。
知识分享能够帮助他人节省时间和精力,于是我决定将自己学习过程中总结的笔记分享给大家,希望能帮助到需要的人。
本文简单介绍了Neo4j的数据模型,总结归纳了CQL语句和py2neo的常用用法。
目前,网上关于py2neo用法的总结内容甚少,本文是对其的补充,使用的是当前最新版本的py2neo 2020
Neo4j
数据模型
- 节点
基本单位,包含多个属性,节点与节点之间可以建立关系
- 属性
键值对
- 关系
具有方向性。每个关系包含一个起始节点和一个结束节点
关系也可以包含属性
- 标签
将一个公共名称与一组节点或关系相关联。
节点或关系可以包含一个或多个标签。
只能通过标签名称来访问节点详细信息
- 数据浏览器
http://localhost:7474/browser/
Neo4j CQL
CREATE
创建节点
node-name只是一个变量名,在语句中用完就没用了
CREATE (<node-name>:<label-name>)
CREATE (<node-name>:<label-name1>:<label-name2>.....:<label-namen>)
CREATE (
<node-name>:<label-name>
{
<Property1-name>:<Property1-Value>
........
<Propertyn-name>:<Propertyn-Value>
}
)
Example:
CREATE(ip:IP{ip:'47.94.134.156',location:'北京市北京市 阿里云 数据中心'})
CREATE(ip:IP{ip:'211.68.69.240',location:'北京市海淀区 北京邮电大学 教育网'})
CREATE(domain:Domain{domain:'arrowqin.top',Country:'中国',Province:'北京',City:'北京',ISP:'阿里云'})
创建关系
MATCH (<node1-label-name>:<node1-name>),(<node2-label-name>:<node2-name>)
CREATE
(<node1-label-name>)-[<relationship-label-name>:<relationship-name>
{<define-properties-list>}]->(<node2-label-name>)
RETURN <relationship-label-name>
Example:
MATCH (ip:IP),(domain:Domain)
CREATE (ip)-[has:has_domain]->(domain)
MATCH (ip:IP{ip:'47.94.134.156'}),(domain:Domain{domain:'arrowqin.top'})
CREATE (ip)-[di:domain_is]->(domain)
MATCH (ip:IP),(domain:Domain)
where ip.ip='47.94.134.156' and domain.domain='arrowqin.top'
CREATE (ip)-[di:domain_is]->(domain)
创建节点和关系
CREATE
(<node1-label-name>:<node1-name>{<define-properties-list>})-
[<relationship-label-name>:<relationship-name>{<define-properties-list>}]
->(<node1-label-name>:<node1-name>{<define-properties-list>})
RETURN <relationship-label-name>
Example:
CREATE (ip:IP{ip:'210.30.199.4',location:'辽宁省沈阳市 东北大学 教育网'})-[di:domain_is]->(domain:Domain{domain:'neu.edu.cn',Country:'中国',Province:'辽宁',City:'沈阳',ISP:'教育网'})
使用MERGE命令创建
只有当目标不存在时,MERGE才会添加到数据库
不存在指:其中至少有一个不同的属性值
Match-Return
语法
MATCH
(
<node-name>:<label-name>
)
RETURN
<node-name>.<property1-name>,
........
<node-name>.<propertyn-name>
查询节点
MATCH Command RETURN Command
Example:
MATCH(ip:IP) RETURN ip
MATCH(ip:IP) RETURN ip.location
MATCH(c:City{`名称`:"Beijing"}) return c
查询关系
MATCH (ip)-[has:has_domain ]->(domain)
RETURN has
使用LIMIT过滤或限制查询返回的行数
LIMIT <number>
Example:
MATCH(ip:IP)
RETURN ip
limit 2
使用SKIP修整CQL查询结果集顶部的结果
SKIP <number>
Example:
MATCH(ip:IP)
RETURN ip
skip 2
WHERE
WHERE <condition> <boolean-operator> <condition>
<condition>
<property-name> <comparison-operator> <value>
Example:
MATCH (ip:IP)
WHERE ip.ip = '47.94.134.156'
RETURN ip
DELETE
删除节点和关系
DELETE <node-name-list>
DELETE <node1-name>,<node2-name>,<relationship-name>
Example:
MATCH (ip:IP{ip:'211.68.69.240'}) DELETE ip
MATCH (ip:IP{ip:'210.30.199.4'})-[di:domain_is]->(domain:Domain{domain:'neu.edu.cn'})
DELETE di
MATCH (ip:IP{ip:'210.30.199.4'})-[di:domain_is]->(domain:Domain{domain:'neu.edu.cn'})
DELETE ip,di,domain
SET
添加属性
SET <property-name-list>
MATCH (ip:IP{ip:'211.68.69.240'})
SET ip.test = 'test'
RETURN ip
MATCH (ip:IP{ip:'211.68.69.240'})
SET ip:TEST
RETURN ip
REMOVE
删除属性
REMOVE <property-name-list>
Example:
MATCH (ip:IP{ip:'211.68.69.240'})
REMOVE ip.test
RETURN ip
删除标签
REMOVE <label-name-list>
Example:
MATCH (ip:IP)
REMOVE ip:TEST
ORDER
ORDER BY <property-name-list> [DESC]
Example:
MATCH (ip:IP)
RETURN ip
ORDER BY ip.ip DESC
UNION
UNION
它将两组结果中的公共行组合并返回到一组结果中。 它不从两个节点返回重复的行。
<MATCH Command1>
UNION
<MATCH Command2>
Example:
MATCH (ip:IP) RETURN ip.ip,ip.location
UNION
MATCH (ip2:IP) RETURN ip2.ip,ip2.location
使用AS子句
MATCH (ip:IP) RETURN ip.ip as p1,ip.location as p2
UNION
MATCH (domain:Domain) RETURN domain.domain as p1 ,domain.ISP as p2
UNION ALL
它结合并返回两个结果集的所有行成一个单一的结果集。它还返回由两个节点重复行。
IN操作符
MATCH(ip:IP)
WHERE ip.ip in ['211.68.69.240','210.30.199.4']
RETURN ip
NULL值
创建一个具有现有节点标签名称但未指定其属性值的节点时,它将创建一个具有NULL属性值的新节点
字符串函数
所有CQL函数应使用“()”括号。
TOUPPER/TOLOWER
输入一个字符串并转换为大/小写字母。
UPPER (<input-string>)
<input-string>可以是来自Neo4J数据库的节点或关系的属性名称
Example:
MATCH (domain:Domain)
RETURN TOUPPER(domain.domain)
SUBSTRING
返回子字符串
SUBSTRING(<input-string>,<startIndex> ,<endIndex>)
Example:
MATCH (ip:IP)
RETURN SUBSTRING(ip.location,0,2)
AGGREGATION聚合函数
COUNT
从MATCH子句获取结果,并计算结果中出现的行数,并返回该计数值
COUNT(<value>)
Example:
MATCH (ip:IP)
RETURN COUNT(*)
MAX,MIN,AVG,MIN 同理
关系函数
STARTNODE/ENDNODE
打印关系的开始/结束节点
STARTNODE (<relationship-label-name>)
<relationship-label-name>可以是来自Neo4j数据库的节点或关系的属性名称
Example:
MATCH (ip)-[di:domain_is]->(domain)
RETURN STARTNODE(di)
ID/TYPE
ID 查找关系的ID
TYPE 查找关系的类型,也就是我们在图表中看到的名称
MATCH (ip)-[di]->(domain)
RETURN ID(di),TYPE(di)
UNIQUE约束
避免重复记录
CREATE CONSTRAINT ON (<label_name>)
ASSERT <property_name> IS UNIQUE
Example:
CREATE CONSTRAINT ON (ip:IP)
ASSERT ip.ip IS UNIQUE
DROP CONSTRAINT ON (<label_name>)
ASSERT <property_name> IS UNIQUE
Example:
DROP CONSTRAINT ON (ip:IP)
ASSERT ip.ip IS UNIQUE
py2neo
官方文档:https://py2neo.readthedocs.io/en/latest/
版本:2020.0.0
安装
pip install py2neo
导入常用的包
from py2neo import Graph,Node,Relationship
from py2neo.matching import *
连接数据库
graph = Graph(password="arrowscan") # username='neo4j'
查看数据库的基本属性
graph.schema.node_labels # 查看节点的所有标签,返回frozenset,通过循环调用返回str
graph.schema.relationship_types # 查看关系的所有类型,返回frozenset,通过循环调用返回str
图数据类型
所有的图数据都可以组合为任意的Subgraph对象
Node
创建
node = Node("Label",Property=Value)
标签
node.labels # 返回节点所有的标签
node.has_label(label)
node.add_label(label)
node.remove_label(label)
node.clear_labels()
node.update_labels(labels) # 增加多个标签,labels为可迭代对象,如list
属性
# 赋值
node[name] = value # 赋值,如果value为空,则删除属性
# 取单值
node[name] # 返回属性值
node.get(name,default=None) #属性不存在返回default值
node.setdefault(name,default=None) # 返回属性值,如果没有值,则设置为default
# 取所有值
node.items() # 返回属性键值对列表
node.keys() # 返回属性名称列表
node.values() # 返回值列表
# 删除
del node[name] # 删除属性,如不存在则报错
node.clear() # 删除所有属性
# 其他
len(node) # 返回属性数量
dict(node) # 转为字典
其他操作
node.graph # 返回节点绑定的graph
node.identity # 返回节点在graph中的ID
hash(node) # 根据ID返回节点的Hash值
Relationship
创建
class relationship_name(Relationship):pass # 关系类
relationship = relationship_name(node1,node2) # 关系
relationship_name = Relationship.type("relationship_name")
relationship = relationship_name(node1,node2)
类型和几何
type(relationship) # 返回关系类
type(relationship).__name__ # 返回关系名称的str
relationship.nodes # 返回关系中的两个节点
relationship.start_node
relationship.end_node
属性及其他操作
与node属性及其他操作相同
Path
略
Subgraph
节点和关系的任意集合
一个Subgraph至少包含一个节点
创建
subgraph = node1 | node2 | relationship # 利用任意节点、关系创建subgraph
Subgraph之间的操作
subgraph = a | b | c # 返回所有节点和关系的子图
subgraph = a & b & c # 返回共有的节点和关系的子图
subgraph = a - b - c
subgraph = a ^ b ^ c
其他操作
subgraph.keys() # 返回所有属性名称的frozenset,通过循环调用返回str
subgraph.labels() # 返回所有标签的frozenset,通过循环调用返回str
subgraph.types() # 返回所有关系类型的frozenset,通过循环调用返回str
subgraph.node # 返回所有节点的集合,通过循环调用返回Node
subgraph.relationships # 返回所有节点的集合,通过循环调用返回Relationship
图数据库
Graph对象
# 创建
graph.create(subgraph) # subgraph可以是Node,Relationship,subgraph
graph.merge(subgraph,label=None,*property_keys) # 根据属性名property_keys来创建或更新数据
# 删除
graph.delete(subgraph)
graph.delete_all() # 删除所有节点和关系
graph.separate(subgraph) # 删除关系,但保留节点
# 查询
graph.exists(subgraph)
graph.nodes # 返回一个包含全部节点的NodeMatcher
graph.relationships # 返回一个包含全部关系的RelationshipMatcher
# 执行CQL
graph.run(cypher) # 执行CQL语句,并返回Cursor,通过循环调用返回Record
# 其他
graph.name # 输出graph的名称
graph.schema
graph.service
匹配节点与关系
NodeMatcher
用于选择节点的匹配器
创建
matcher = NodeMatcher(graph)
操作
len(matcher) # 返回节点的数量
node_id in matcher # 判断ID为node_id的节点是否存在
matcher[node_id] # 返回ID为node_id的节点,不存在将报错,返回Node类型
matcher.get(node_id) # 返回ID为node_id的节点,不存在返回None,返回Node类型
matcher.match(*labels, **properties) # 匹配并返回具有特定条件的所有NodeMatch类型
example:
matcher.match("IP", ip="47.94.134.156").first()
NodeMatch
节点集合:由NodeMatcher.match产生
len(match)
match.count()
match.all() # [节点列表]
match.first() # 返回第一个 Node类型
match.limit(amount)
match.skip(amount)
match.exists() # True:至少存在一个节点
match.where(*predicates, **properties) # 返回NodeMatch类型
example:
match.where(ip="47.94.134.156").all()
RelationshipMatcher
用于选择关系的匹配器
创建
matcher = RelationshipMatcher(graph)
操作
len(matcher) # 返回关系的数量
relationship_id in matcher # 判断ID为relationship_id的关系是否存在
matcher[relationship_id] # 返回ID为relationship_id的关系,不存在将报错,返回Relationship类型
matcher.get(relationship_id) # 返回ID为relationship_id的关系,不存在返回None,返回Relationship类型
matcher.match(nodes=None, r_type=None, **properties) # 匹配并返回具有特定条件的所有RelationshipMatch类型
example:
matcher.match(nodes=None, r_type=None)
# nodes 开始节点和结束节点的序列或集合,集合表示在任何方向上匹配,None表示任何节点
# r_type 匹配的关系类型 None表示任何类型
RelationshipMatch
同NodeMatch
应用谓词
IS_NULL()
IS_NOT_NULL()
EQ(value)
NE(value)
LT(value) # <
LE(value) # <=
GT(value)
GE(value)
START_WITH(value)
ENDS_WITH(value)
CONTAINS(value)
LIKE(regex)
IN(value)
AND() # 满足全部条件
OR()
XOR()
example:
nodes.match("IP", ip=STARTS_WITH("47")).all()
nodes.match("IP", ip=LIKE("47.*?156")).all()
nodes.match("IP", ip=IN(['47.94.134.156','211.68.69.240']))
nodes.match("Person", born=AND(GE(1964), LE(1966))).all()