neo4j应用场景
- 知识图谱
- 欺诈检测
- 实时推荐引擎
- 反洗钱
- 主数据管理
- 供应链管理
- 增强网络和IT运营管理能力
- 数据谱系
- 身份和访问管理
- 材料清单
图数据库neo4j简介
关系查询:mysql和neo4j性能对比
neo4j的特性和优点:
Neo4j-CQL简介
neo4j的Cypher语言是为处理图形数据而构建的,CQL代表Cypher的查询语言,像oracle数据库具有查询语言SQL
常用命令
1. 同时创建节点和关系
create (n1:class {name:"英语1"})-[r:BASIC]->(n2:class2 {name:"英语2"})
2. 批量删除节点
with [42,43,44,45] as nodeIds unwind nodeIds as nodeId match (n) where id(n) = nodeId delete n
3. 删除当前节点下的所有关系(删除节点前必须做此操作)
match (n)-[r]-() where id(n)=46 delete r
4. 为已经存在的节点创建关系
match (a:class {name:"英语1"}),(b:class2 {name:"英语2"}) create (a)-[r:BASIC]->(b)
5. 删除当前节点下的指定关系(根据关系id删除)
match (n)-[r]-() where id(n)=46 and id(r)=0 delete r
6. 根据关系id删除关系
match (n)-[r]-() where id(r)=1 delete r
7. 删除全部节点和关系
match (n) detach delete n
8. 创建关系时,给关系增加属性
match (n1 {name:"大学英语III"}), (n2 {name:"大学英语IV"}) create (n1)-[r:BASIC {since: 2023}]->(n2)
9. 根据标签查找当前节点以及它的关系节点
match (n:profession {name:"计算机专业"})-[r]->(n2) return n,n2
10. 根据关系名称查找:当前节点往后走的整个链条(递归调用)
方法1:match path = (n {name:"大学英语II"})-[r:BASIC*]->() return nodes(path)
方法2:match path = (n)-[r:BASIC*]->() where n.name="大学英语II" return nodes(path)
11. 根据关系名称查找:当前节点有关系的整个链条
match path = (n)-[r:BASIC*]-() where n.name="大学英语III" return nodes(path)
12. 查看标签有多少个节点
match (n:Person) return count(n) as person_count
13. 删除标签中的所有节点(同时自动删除它们的关系)
match (n:Person) detach delete n
14. 创建一对节点(同时建立它们的联系)
create (n1:Person{name:"张三"})-[r:couple{roles:"boyfriend"}]->(n2:Person{name:"rose"})
15. merge也可以创建两个节点之间的关系
match (n:Person {name:"Shawn"}),(n2:Person {name:"Sally"}) merge (n)-[:FRIENDS {since:2023}]->(n2)
16. csv文件导入
load csv from "file:///test.csv" as line create (:Article {name:line[1], year: toInteger(line[2])})
17. 移除节点对应的标签
match (n:Student {name:"李四"}) remove n:Student return n
18. 给已有节点添加标签
match (n {name:"李四"}) set n:Person return n
19. 移除节点属性
match (n:Person) where n.name="李四" remove n.age return n
20. 按照节点属性进行排序
match (n:Student) return id(n) as id order by id asc
21. 其它命令
* union: 拼接两个查询语句,不返回重复的行
* union all: 拼接两个查询语句,返回重复的行
* limit n: 选择前几行
* skip n: 跳过前几行
22. 给已有节点添加属性
match (n:Student) where n.name="张三" set n.age=18,n.sex="女" return n
23. null值查询
match (n:Student) where n.sex is null return n
24. in查询
match (n:Student) where n.name in ["张三", "小红"] return n
25. index索引
* 创建索引
create index on :Student (name)
* 删除索引
drop index on :Student (name)
26. unique约束
* 创建唯一性约束
create constraint on (n:Student) assert n.name is unique
* 删除唯一性约束
drop constraint on (n:Student) assert n.name is unique
常用函数
-
字符串函数
-
聚合函数
-
关系函数
Neo4j-admin的使用
对neo4j数据进行备份、还原、迁移操作时,要关闭neo4j
-
数据库备份
/home/neo4j/neo4j-community-3.5.2/bin/neo4j-admin dump --database=graph.db --to=/root/graph_back.dump
-
数据库恢复
# 数据导入 /home/neo4j/neo4j-community-3.5.2/bin/neo4j-admin load --from=/root/graph_back.dump --database=graph.db --force # 重启服务 neo4j start
python操作neo4j
-
安装py2neo
pip install py2neo==2020.1.0
-
创建图对象
import time from py2neo import Graph graph = Graph("http://localhost:7474", username="neo4j", password="123456") print(graph)
-
Node
#获取key对应的property x=node[key] #设置key键对应的value,如果value是None就移除这个property node[key] = value #也可以专门删除某个property del node[key] #返回node里面property的个数 len(node) #返回所以和这个节点有关的label labels=node.labels #删除某个label node.labels.remove(labelname) #将node的所有property以dictionary的形式返回 dict(node)
-
Relationship
#创建Relationship Relationship`(*start_node*, *type*, *end_node*, ***properties*) #返回Relationship的property Relationship[key] #删除某个property del Relationship[key] #将relationship的所有property以dictionary的形式返回 dict(relationship)
-
创建一段关系链
from py2neo import Graph, Node, Relationship g = Graph("http://localhost:7474", username="neo4j", password="123456") a = Node("Person", name="Alice") b = Node("Person", name="Bob") ab = Relationship(a, "KNOWS", b) g.create(ab)
-
数据准备
from py2neo import Graph, Node, Relationship, Subgraph g = Graph("http://localhost:7474", username="neo4j", password="123456") tx = g.begin() jiazhen = Node("Person", name="陈家珍", age=66) fugui = Node("Person", name="徐富贵", age=67) youqian = Node("Person", name="徐有钱") renxing = Node("Person", name="徐任性") cat = Node("Person", name="cat") dog = Node("Person", name="dog") wife = Relationship(fugui, "WIFE", jiazhen) brother_1 = Relationship(fugui, "BROTHER", youqian) brother_2 = Relationship(fugui, "BROTHER", renxing) hus = Relationship(jiazhen, "HUS", fugui) know = Relationship(cat, "KNOWS", dog) relation_list = Subgraph(relationships=[wife, brother_1, brother_2, hus, know]) tx.create(relation_list) tx.commit()
-
query
-
匹配所有节点
from py2neo import Graph, Node, Relationship, Subgraph g = Graph("http://localhost:7474", username="neo4j", password="123456") nodes = g.nodes.match() for node in nodes: print(node) print(node.items()) print(node.labels)
-
匹配符合指定条件的节点
from py2neo import Graph, Node, Relationship, NodeMatcher, Subgraph g = Graph("http://localhost:7474", username="neo4j", password="123456") # 用来查找节点对象 matcher = NodeMatcher(g) # first返回第一个符合条件的节点 node1 = matcher.match("Person", name="徐有钱").first() print(node1) print(node1["name"]) # all返回所有符合条件的节点 nodes = matcher.match("Person").all() for node in nodes: print(node, node["name"]) # 按照节点的年龄属性查找 nodes = matcher.match("Person", age=66).all() print("*" * 25 + "年龄66" + "*" * 25) for node in nodes: print(node["name"], node["age"]) # 模糊匹配,要用Cypher nodes = matcher.match("Person").where("_.name =~ '徐.*'").all() print("*" * 25 + "姓徐的节点" + "*" * 25) for node in nodes: print(node["name"], node["age"])
-
更新
- 更新要先找出nodes,在使用事务的push更新
from py2neo import Graph, Node, Relationship, NodeMatcher, Subgraph g = Graph("http://localhost:7474", username="neo4j", password="123456") tx = g.begin() # 找到你要招的nodes matcher = NodeMatcher(g) # 修改单个节点 """ init_node = matcher.match("Person", name="徐富贵") new_node = init_node.first() new_node["name"] = "富贵" sub = Subgraph(nodes=[new_node]) tx.push(sub) tx.commit() """ # 修改多个节点 init_node = matcher.match("Person") nodes = init_node.all() new_nodes = [] for node in nodes: node["name"] = "哈哈-" + node["name"] new_nodes.append(node) sub = Subgraph(nodes=new_nodes) tx.push(sub) tx.commit()
-
两个节点新加关系
fugui = matcher.match("Person", name="富贵").first() youqian = matcher.match("Person", name="徐有钱").first() relation = Relationship(fugui, "Brother", youqian) g.create(relation)
-
删除
-
删除关系链
注意:删除关系时节点自动删除
matcher = NodeMatcher(g) r_matcher = RelationshipMatcher(g) fugui = matcher.match("Person", name="富贵").first() youqian = matcher.match("Person", name="徐有钱").first() relation = r_matcher.match(nodes=[fugui, youqian]).first() # 如果此处nodes里面写None,会匹配所有关系 g.delete(relation)
-
-
只删除关系,不删除节点
matcher = NodeMatcher(g) r_matcher = RelationshipMatcher(g) cat = matcher.match("Person", name="cat").first() dog = matcher.match("Person", name="dog").first() relation = r_matcher.match(nodes=[cat, dog]).first() g.separate(relation)
-
批处理
对于大量的插入一般是很费时的,首先我们可以使用事务,加快一定速度,而插入的方法一样重要,我们很多时候是遍历一个文件然后生成图,例子中我们生成每个Node后,先把他们放入一个List中,再变为Subgraph实例,然后再create(),耗时比一条条插入至少快10倍以上
- 创建多个节点
-
tx = g.begin()
node_list = [Node("Num", name=str(num+1)) for num in range(4)]
node_list = Subgraph(nodes=node_list)
tx.create(node_list)
tx.commit()
-
删除所有关系
tx = g.begin() r_matcher = RelationshipMatcher(g) relations = r_matcher.match().all() sub_list = Subgraph(relationships=relations) tx.separate(sub_list) # 删除关系,不删除节点 tx.commit()