图数据库
包含节点和关系
- 节点:有属性(键值对形式存储),也可以有多个标签
- 关系:有名字和方向,并总是有一个开始节点和结束节点
neo4j图数据库
通常来讲,对于 10 亿节点以下规模的图谱来说 Neo4j 已经足够了。
pip安装用这个版本...
pip install py2neo==3.1.2
blog.csdnimg.cn/20191008195700521.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNjEwNDM2,size_16,color_FFFFFF,t_70)
在neo4j目录输入start
可以后台启动,在浏览器输入localhost:7474
进入界面,初始密码是neo4j,之后我们可以初始化我们的neo4j数据库(导入数据)。
导入demo:
.bin/neo4j-admin import --nodes Person.csv --nodes Phone.csv --nodes Application.csv --relationships Person_Application.csv --relationships Person_Relation.csv --relationships Phone_Phone.csv --relationships Person_Phone.csv
很简单的,nodes导入节点,realtionships导入关系。
APOC组件
需要安装:
- apoc-3.4.0.3-all.jar
- mysql-connector-java-5.1.21.jar
APOC的功能:
- 文本和索引查找(提供索引查询、管理全文图标和搜索等功能)
- 实用函数(域名提取、时间和日期、数值格式转换等功能)
- 图算法(社区检测、pagerank、中心算法等)
- 空间函数(地理编码、位置编码、空间和时间搜索等)
- 数据集成(json、jdbc、csv等格式数据的加载)
- 图形重构(节点合并、属性规范化与分类等)
- 虚拟节点/关系(提供虚拟图的创建)
- cypher操作(单个和多个cypher语句运行和脚本运行)
- 触发器(与关系型数据库的触发器的理解方式一样)
- ……
APOC数据集成-JDBC
apoc.load.jdbc:可以访问提供JDBC驱动程序的数据库, 并执行查询。其将结果变成以一行数据为单位的数据流。然后可以使用功能这些行来更新或创建图形数据结构
call apoc.load.jdbc("jdbc:mysql://{IP):{PORT}/{DBNAME}? user={USERNAME}&password={PASSWORD}","{TABLENAME}") yield row
创建节点的语句,使用row.
调用每一行中的具体字段(一行行的返回数据)
假如有一个黑名单表,有block_id字段和type字段
create (b:Black{number:row.block_id,type:row.type})
但是要注意的是导入的数据是设定关系的。
下一步可以打开neo4j查看导入的数据(neo4j存储的数据在neo4j目录下的data/databases/graph.db下)
Cypher 语句
py2neo连接:
authenticate("localhost:7474", "neo4j", "1234")
graph = Graph(
"http://localhost:7474/db/data/",
user="neo4j",
password="1234")
首先启动neo4j,打开浏览器查看。可以在浏览器界面命令交互。
match (node)-[relationship]->(node)
where (node | relationship)
return (node | realtioinship)
demo(不带关系的查询):
match (n:Person) retuen n limit 10
n 就是Person的别名, 返回n,限制条件是10个
demo(带关系的查询):
match (n:Person)-[:HAS_PHONE]->(p:Phone) return n,p limit 10
查找有手机的人
demo(带有条件的查询):
match (n:Person)-[:HAS_PHONE]->(p:Phone) where n.name="liao" return n,p limit 10
查找姓名为liao的关系
demo(2度关系):
match (n:Person) -[:HAS_PHONE]->(p:Phone)-[:CALL]-(p1:Phone) where n.name='liao' return n limit 10
查找有电话的人,同时还显示所持有的电话打过的电话的节点
demo(利用关系查询):
math p=()-[c:CALL]-() return p limit 10
不限制实体,通过关系(call)查询
demo(利用正则查询):
match (n:Users) where n.name=~"liao.*" return n limit 10
~符号后面可以利用正则查询
demo(包含查询):
match (n:Users) where n.name contains "l" return n limit 10
名字里面包含l的
创建实体与关系:
demo(创建简单的实体与关系):
create (n:Person)-[:LOVES]->(m:Dog)
demo(创建带有属性的实体与关系):
create (n:Person{name:“李四”’})-[:FEAR{level:1}]->(t:Tiger{type:"东北"})
给两个孤立的实体创建关系
创建相同的关系时原来的关系不会被替换,即使时相同的关系也不会替换:
match (n:Person{name:"liao"}), (m:Person{name:"luo}), create (n)-[v:LOVE]->(m) return v
merge(有则返回,没有这创建)
match (n:Person{name:"liao"}), (m:Person{name:"luo"}) merge (n)-[v:LOVE]->(m) return 1
删除
这里删除会将所选择的所有hate
关系删除:
match (n:Person{name:"lishi"})-[v:hate]->(m:Person{name:"zhangshan"}) delete v
删除节点 ,但在删除实体之前必须删除关系:
match (n:Person{name:"lishi"}) delete n
或者可以同时删除实体与关系:
match (n:Person)-[l:love]->(d:Dog) delete n,l,d
更新实体
这样会添加一个新的标签:
match (t:Tiger) where id(t)=123 set t:Person return t
更新属性:
match (n:Person) wherer id(n)= 123 set n.new_ele="new_ele" return n
在关系上添加属性:
match (n:Person) -[v:love]->(:Person) set l.date="1990" return n
Cypher 的复杂查询
题目:姓名12 ,3度之内的朋友有哪些:
(注意,这里的关系我们可以使用无向的,即无>箭头的)
match (p:Person)-[:FRIEND_OF]-(p1:Person)-[:FRIEND_OF]-(p2:Person) where p.name="姓名12" return p,p1,p2
题目:姓名11 的通话记录中的电话有哪些:
match (p:Person)-[:HAS_Phone]->(p2:Phone)-[:CALL]-(h:Phone) where p.name="姓名11" return p,p2
题目:姓名2与姓名10之间的最短路径(里面的关系[*…10]表示10度关系以内),最后返回路径
match (p:Person{name:‘姓名2}),(p2:Person{name:"姓名10"}), p=shortestpath((p1)-[*..10]-(p2)) return p
题目:返回目标之间的所有最短路径:
match (p:Person{name:‘姓名2}),(p2:Person{name:"姓名10"}), p=allshortestpaths((p1)-[*..10]-(p2)) return p
规则的存储
-
规则存储 -> 微服务 -> neo4j
-
存储到数据库中:
- 优点:进行规则的添加时,不用修改程序
- 缺点:每次取规则时都需读一次数据库
-
写在存续的配置文件里:
- 优点:读取速度比数据库快
- 缺点:万一要修改规则,,那么就要修改代码
规则的开发
- 申请人之前有多少个逾期的进件
match (p:Person) -[h:HAS_APPLICATION]->(a:Application) where a.status="OVER_DUE" and p.personId="243001" return count(a)
- 申请人的一度关系中有多少个触碰黑名单(我们标定黑名单不是直接标定任务而是标定他的手机或者银行卡)
match (p:Person)-[]-(p1:Person)-[h:HAS_PHONE]-(b:BLOCK) where p.personId="243001" return count(b)
- 申请人的二度关系中有多少触控黑名单
match (p.Person)-[]-(p1:Person)-[]-(p2:Person)-[h:HAS_PHONE]-(b:BLOCK) where p.personId="243001" return count(b)