一般情况下,我们使用数据库查找事物间的联系的时候,只需要短程关系的查询(两层以内的关联)。当需要进行更长程的,更广范围的关系查询时,就需要图数据库的功能。

而随着社交、电商、金融、零售、物联网等行业的快速发展,现实世界的事物之间织起了一张巨大复杂的关系网,传统数据库面对这样复杂关系往往束手无策。因此,图数据库应运而生。

图数据库(Graph database)指的是以图数据结构的形式来存储和查询数据的数据库。

从 http://db-engines.com/en/ranking 可以发现,Neo4j 是目前用的最多的图数据库,世界数据库排行榜上排名21位。

Neo4J属于原生图数据库,其使用的存储后端专门为图结构数据的存储和管理进行定制和优化的,在图上互相关联的节点在数据库中的物理地址也指向彼此,因此更能发挥出图结构形式数据的优势。

知识图谱中,知识的组织形式采用的就是图结构,所以非常适合用neo4j进行存储

图数据库的优势在于:

数据存储形式

neo4j的数据存储形式 主要是 节点(node)和 边(edge) 来组织数据。node可以代表知识图谱中的实体,edge可以用来代表实体间的关系,关系可以有方向,两端对应开始节点和结束节点。

另外,可以在node上加一个或多个标签(Node Label)表示实体的分类,以及一个键值对集合来表示该实体除了关系属性之外的一些额外属性。关系也可以附带额外的属性。

查询语言cypher

neo4j采用自己设计的查询语言cypher,其特点和sql有很多相似的地方。match、where、return是最常用到的关键词:

安装neo4j

这里我们使用docker安装neo4j,安装命令行如下:

docker run -d --name=Neo4j\    --publish=7474:7474 --publish=7687:7687 \    --volume=$HOME/neo4j/data:/data --volume=$HOME/neo4j/import:/import\    neo4j
    --volume=$HOME/neo4j/data:/data --volume=$HOME/neo4j/import:/import\
    neo4j

根据配置参数,我们将容器内的7474端口挂载到外部宿主机的7474端口,并设置好文件夹的映射关系,注意/import文件夹下放的是将要导入数据库的csv文件。

接着在浏览器中打开 “ http://localhost:7474/ ”,就可以访问Neo4j管理界面了。

neo4j网页管理界面

我们通过一个例子来说明如何运用neo4j数据库。

1. 导入数据

我们这里有两个csv文件如下图,左边的nodes_companies.csv是一部分公司节点,右边的edges_director_duration.csv是这些公司互相之间的服务关系

nodes_companies.csv文件和edges_director_duration.csv

把这两个文件放到neo4j根目录下的import文件夹内,使用LOAD…AS row语句读取,表示将csv文件按行读取,每行的变量名为row。再使用MERGE指令创建节点,将csv文件的第一列数据与第二列数据汇总为一个结点内的两条属性信息。

LOAD CSV WITH HEADERS FROM "file:///nodes_companies.csv" AS rowMERGE (c:Company {companyId:row.companyId, companyName:row.name})WITH HEADERS FROM "file:///nodes_companies.csv" AS row
MERGE (c:Company {companyId:row.companyId, companyName:row.name})

这里提一下cypher中两个用于创建新的数据的两个关键词: create 和 merge

merge:在数据库中可以匹配到模式相同的数据就返回,没有则创建一条这样的数据(有则返回,没有则创建

create:无论如何,都会创建一条新的数据

上面再LOAD文件时使用merge可以避免导入完全重复的数据

导入公司节点

通过第二个csv文件的START_ID和END_ID字段为第一个csv文件的company之间建立联系,即不断遍历第二个文件的每一行,根据START_ID和END_ID使用where找到图中相应节点,并为它们添加相应的服务(INTERLOCK)关系,添加关系属性为weight。

LOAD CSV WITH HEADERS FROM "file:///edges_director_duration.csv" AS rowmatch (c1:company), (c2:company)where row.START_ID = c1.id and row.END_ID = c2.idcreate (c1)-[r:INTERLOCK{weight:row.years_served}]->(c2)WITH HEADERS FROM "file:///edges_director_duration.csv" AS row
match (c1:company), (c2:company)
where row.START_ID = c1.id and row.END_ID = c2.id
create (c1)-[r:INTERLOCK{weight:row.years_served}]->(c2)

注意在cypher语句里,节点是用()括起来表示,关系则用 [] 括起来表示

导入公司关系

2.创建关系

这里我们尝试自己创建一条新的关系,比如在id = 281 和 id = 879 的两个节点间创建一条标签为“INTERLOCK”的关系。

先match和where锁定 id = 281 和 id = 879的两个公司节点,然后用create创建他们之间的关系,并添加特定关系属性信息(例如weight为10)。

cypher语句如下:

MATCH (c1:company),(c2:company) WHERE c1.id = “281” AND c2.id = “879” CREATE (c1)-[r:INTERLOCK{weight:10}]->(c2) RETURN (c1)-[r]-(c2)CREATE (c1)-[r:INTERLOCK{weight:10}]->(c2) RETURN (c1)-[r]-(c2)

这条语句的意思是,匹配类别标签为company,id分别等于281和879的两个公司节点,设置变量名为c1和c2,在他们之间创建关系,关系变量名为r,这里 ()-[]-() 代表无向边,()-[]->() 代表有向边

返回结果 (c1)-[r]-(c2) 匹配到的子图如下所示:

创建新的关系

3.比较复杂的查询

下面这条语句会把所有公司中,指向其他公司的连接关系数超过75条的公司全部找出来。用空括号()代表任一节点,函数count() 计算关系的数量。

MATCH (c:company)-[r:INTERLOCK]->() WITH c, count(r) as relaNum WHERE relaNum>=75 RETURN c,relaNum

4.最短路径查询

neo4j还还内置实现了一套图搜索算法,并提供了相关函数接口,比如你想查询两个节点之间的最短路径,就可以用下面的查询语句:

match (c1:company), (c2:company), p=shortestPath((c1)-[r:INTERLOCK*..10]->(c2))where c1.id <> c2.idreturn p,length(p) order by length(p) desc limit 1000
return p,length(p) order by length(p) desc limit 1000

直接调用函数shortestPath,传入的参数为选定的关系,选取任意两个节点,<>表示id不相等,因为查找的两个点不能是同一个点,*..10表示10度以内的所有关系,返回降序排序的长度,限制在1000个防止内存溢出)

MATCH (c1:company), (c2:company), p = allshortestpaths((c1)-[r:INTERLOCK*]-(c2))WHERE c1.id <> c2.idRETURN extract(n in nodes(p)|n.name) as Nodes, length(p) as pathLength,reduce(s=0, e in relationships(p)| s + toInt(e.weight)) as pathDist LIMIT 1000
RETURN 
extract(n in nodes(p)|n.name) as Nodes, 
length(p) as pathLength,
reduce(s=0, e in relationships(p)| s + toInt(e.weight)) as pathDist 
LIMIT 1000

allshortestpaths函数返回结果

语句中的pathLength是路径的边数(第一句return),pathDist是路径上所有带weight边的加权总和(第二句return)。

欢迎关注磐创博客资源汇总站:

http://docs.panchuang.net/

欢迎关注PyTorch官方中文教程站:

http://pytorch.panchuang.net/

​知识图谱里的知识存储:neo4j的介绍和使用的更多相关文章

  1. 知识图谱+Recorder︱中文知识图谱API与工具、科研机构与算法框架

    目录 分为两个部分,笔者看到的知识图谱在商业领域的应用,外加看到的一些算法框架与研究机构. 文章目录 @ 一.知识图谱商业应用 01 唯品金融大数据 02 PlantData知识图谱数据智能平台 03 ...

  2. 知识图谱里的知识表示:RDF

    大部分知识图谱使用RDF描述世界上的各种资源,并以三元组的形式保存到知识库中.RDF( Resource Description Framework, 资源描述框架)是一种资源描述语言,它受到元数据标 ...

  3. 知识图谱之图数据库Neo4j

    知识图谱中的知识是通过RDF结构来进行表示的,其基本单元是事实.每个事实是一个三元组(S, P, O),在实际系统中,按照存储方式的不同,知识图谱的存储可以分为基于表结构的存储和基于图结构的存储. 基 ...

  4. 知识图谱和neo4j的基本操作

    一.知识图谱的简介 1.知识图谱是什么 知识图谱本质上是语义网络(Semantic Network)的知识库 可以理解为一个关系图网络. 2.什么是图 图(Graph)是由节点(Vertex)和边(E ...

  5. 1. 通俗易懂解释知识图谱(Knowledge Graph)

    1. 通俗易懂解释知识图谱(Knowledge Graph) 2. 知识图谱-命名实体识别(NER)详解 3. 哈工大LTP解析 1. 前言 从一开始的Google搜索,到现在的聊天机器人.大数据风控 ...

  6. 2. 知识图谱-命名实体识别(NER)详解

    1. 通俗易懂解释知识图谱(Knowledge Graph) 2. 知识图谱-命名实体识别(NER)详解 3. 哈工大LTP解析 1. 前言 在解了知识图谱的全貌之后,我们现在慢慢的开始深入的学习知识 ...

  7. 知识图谱推理与实践 (2) -- 基于jena实现规则推理

    本章,介绍 基于jena的规则引擎实现推理,并通过两个例子介绍如何coding实现. 规则引擎概述 jena包含了一个通用的规则推理机,可以在RDFS和OWL推理机使用,也可以单独使用. 推理机支持在 ...

  8. 知识图谱辅助金融领域NLP任务

    从人工智能学科诞生之初起,自然语言处理(NLP)就是人工智能核心的研究问题之一.NLP的重要性是毋庸置疑的,它能够实现以自然语言交流为特征的高级人机交互,使机器能“阅读”所有以文字形式记录的人类知识, ...

  9. ISWC 2018概览:知识图谱与机器学习

    语义网的愿景活跃且良好,广泛应用于行业 语义网的愿景是「对计算机有意义」的数据网络(正如 Tim Berners Lee.James Hendler 和 Ora Lassila 在<科学美国人& ...

随机推荐

  1. 一篇文章带您读懂List集合(源码分析)

    今天要分享的Java集合是List,主要是针对它的常见实现类ArrayList进行讲解 内容目录 什么是List核心方法源码剖析1.文档注释2.构造方法3.add()3.remove()如何提升Arr ...

  2. eggjs+vue+nginx配置

    安装node https://github.com/nodesource/distributions#installation-instructions-1 注意使用No root privilege ...

  3. 用table类型布局一个新闻网页

    <html><head><meta http-equiv="Content-Type" content="text/html; charse ...

  4. 前端的事件冒泡(例如点击一次onclick事件执行两次)解决办法

    问题概要: 当我运用antd 中 radio组件的时候发现radio组件是有bug的 就是你不能给他赋予id 和 value,同时也绑定不上onclick等事件.举个例子: 可以看到 你就算赋予了id ...

  5. 微信小程序注册和简单配置

    微信小程序注册 1.直接搜索微信小程序,按照流程进行注册 2.如果有微信公众号,可以在公众号内部点小程序,进入注册流程 小程序中的概念 开发设置 在开发设置中获取AppID和AppSecret App ...

  6. css 居中方法

    垂直居中 利用“精灵元素”(ghost element)技术实现垂直居中,即在父容器内放一个100%高度的伪元素,让文本和伪元素垂直对齐,从而达到垂直居中的目的. .ghost-center { po ...

  7. VUE三 vue-router(路由)详解

    前端路由 根据不同的 url 地址展示不同的内容或页面,无需依赖服务器根据不同URL进行页面展示操作 优点 用户体验好,不需要每次都从服务器全部获取,快速展现给用户 缺点 使用浏览器的前进,后退键的时 ...

  8. 转:标签中的href如何调用js

      在HTML中,<a>标签的href属性用于指定超链接的目标的URL.在所有浏览器中,链接的默认外观是: 未被访问的链接带有下划线而且是蓝色的 已被访问的链接带有下划线而且是紫色的 活动 ...

  9. Vue2.0 【第二季】第2节 Vue.extend构造器的延伸

    目录 Vue2.0 [第二季]第2节 Vue.extend构造器的延伸 一.什么是Vue.extend 二.自定义无参数标签 三.挂载到普通标签上 Vue2.0 [第二季]第2节 Vue.extend ...

  10. 关于动态路由中路由之间的跳转(页面a跳转到页面b)

    由addRouters方法获取到后台的动态路由,要实现路由之间的跳转,不可直接用path: '***',而是将动态路由存储到vuex中,再从vuex中取得,如:this.$store.menu.nav ...