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

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

图数据库(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. 事务Transaction

    目录 为什么写这系列的文章 事务概念 ACID 并发事务导致的问题 脏读(Dirty Read) 非重复读(Nonrepeatable Read) 幻读(Phantom Reads) 丢失修改(Los ...

  2. C++走向远洋——21(项目一,三角形,类)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:sanjiaoxing.cpp * 作者:常轩 * 微信公众号: ...

  3. python 保存两位小数

    一.代码 import decimal decimal.getcontext().rounding = decimal.ROUND_HALF_UP def index(number): n = str ...

  4. paillier加密算法原理详解

    paillier加密算法是一种公钥加密算法,基于复合剩余类的困难问题.满足加法同态,即密文相乘等于明文相加:D(E(m1)·E(m2))=m1+m2.这里详细介绍其加密解密是如何推导的,需要具备数论. ...

  5. Matplotlib数据可视化(4):折线图与散点图

    In [1]: from matplotlib import pyplot as plt import numpy as np import matplotlib as mpl mpl.rcParam ...

  6. 难住了同事:Java 方法调用到底是传值还是传引用

    Java 方法调用中的参数是值传递还是引用传递呢?相信每个做开发的同学都碰到过传这个问题,不光是做 Java 的同学,用 C#.Python 开发的同学同样肯定遇到过这个问题,而且很有可能不止一次. ...

  7. 当微信小程序遇上filter~

    在微信小程序的开发过程中,当你想要实现不同页面间的数据绑定,却为此抓耳饶腮时,不妨让微信小程序与filter 来一场完美的邂逅,相信会给你带来别样的惊喜~ 前段时间被安利了一个很实用的公众号-前端早读 ...

  8. 前端每日实战:151# 视频演示如何用纯 CSS 创作超能陆战队的大白

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/ReGRaO 可交互视频 此视频是可 ...

  9. Java easyui 下拉框默认选中第一个

    html代码: <tr> <td> <div style="margin-bottom:5px">计价方式:   <%--下拉框默认选中第 ...

  10. celery异步任务 定时任务

    以前项目中用到过 celery ,但是没怎么记笔记,现在在记一下,方便以后用.   Celery.png 问:Celery 是什么? 答:Celery 是一个由 Python 编写的简单.灵活.可靠的 ...