google Cayley图谱数据库初试
一.安装
mkdir cayley
cd cayley
mkdir src
export GOPATH=$(pwd)
go get github.com/google/cayley
go build src/github.com/google/cayley/cayley.go
其中缺什么包下什么包,没有hg工具安装hg
修改下源码cayley.go
switch cmd {
case "init":
db.Init(cfg, *tripleFile)
case "load":
ts, _ = db.Open(cfg)
db.Load(ts, cfg, *tripleFile)
ts.Close()
case "repl":
ts, _ = db.Open(cfg)
db.Repl(ts, *queryLanguage, cfg)
ts.Close()
case "http":
ts, _ := db.Open(cfg)
http.Serve(ts, cfg)
ts.Close()
default:
fmt.Println("No command", cmd)
flag.Usage()
}
运行
go build $GOPATH/src/github.com/google/cayley/cayley.go && ./cayley http --port=8080 --assets=$GOPATH/src/github.com/google/cayley --dbpath=src/testdata.nt
assets 参数代表启动http server以后存放html静态资源的目录,源码里是自带的
dbpath 是数据库的一些初始化数据,必须指定,不然启动了,也没法添加数据,默认是指定为/tmp/testdb文件
在浏览器输入http://127.0.0.1:8080/如果有页面输出说明成功了
二.基本概念
testdata.nt内容如下
alice follows bob .
bob follows alice .
charlie follows bob .
dani follows charlie .
dani follows alice .
alice is cool .
bob is "not cool" .
charlie is cool .
dani is "not cool" .
内容的每行都是以空格分隔的四元组,每一行叫做一个Triple,存储多个Triple组成了TripleStore,每个Triple由四部分组成,依次对应数据每行用空格分隔的每项,分别叫Subject,Predicate,Object,Provenance。对应中文里的,Subject是中文里的主语,Predicate是中文里的谓语,Object是宾语,Provenance是来源。也就是说,每行描述了,谁怎么样了XX,或者谁是XX样的。Subject转换成有向图中的顶点,Object是出度的顶点,Predicate是路径。
cayley搭了一套图数据库的框架,官方提供了三种存储memory,leveldb,mongodb 可以切换存储引擎,只需要实现接口,就可以扩展存储方式,和mysql与innodb的关系差不多。
三.使用API
1. g.V()
取一个图中的顶点,也就是Triple中的Subject,返回一个点的对象
2. path.Out([predicatePath], [tags])
Out是取一个顶点的出度。不过,这个出度是按照谓词区分的,当Out()不传递参数的时候,是取出某个顶点不按路径区分的所有出度;当Out传递了predicatePath参数的时候,是取出某个顶点,在某个路径上的所有出度。tags 是用来存储路径的名称。例如:
我们入库的数据中以alice顶点为例,
alice follows bob
alice is cool
可以看出alice这个顶点有两个路径,分别是follows和is
(1) 查询allice的所有出度
g.V("alice").All()
(2) 查询alice的关注:
g.V("alice").Out("follows").All()
(3) 查询allice是否很cool
g.V("alice").Out("is").All()
(4) 查询alice的关注和是否很cool
g.V("alice").Out(["follows", "is"]).All()
"result": [
{
"id": "bob"
},
{
"id": "cool"
}
]
(5) 虽然你可以直观的看到,alice的关注是bob,并且alice是个很酷的人,那是因为是通过字面意思,比如有些人follows为空,有些人is为空,那就没法判断返回的出度在哪个路径上,这个时候应该使用tag参数
g.V("alice").Out(["follows", "is"], "path").All()
3. path.In([predicatePath], [tags])
和Out正好相反,是求的入度。
(1) 求所有cool的人
g.V("cool").In("is").All()
(2) alice的粉丝
g.V("alice").In("follows").All()
4. path.Both([predicatePath], [tags])
In和Out的的结果并集,没有去重
5. path.Has(predicate, object)
反向查找,paredicate是路径,object是三元组中的宾语
(1) 查找alice的粉丝
g.V().Has("follows", "alice").All()
6.path.Follow(morphism)
通过管道加速
g.V().Has("name","Casablanca") .Out("/film/film/starring").Out("/film/performance/actor") .Out("name").All()
等价于
var filmToActor = g.Morphism().Out("/film/film/starring").Out("/film/performance/actor")
g.V().Has("name", "Casablanca").Follow(filmToActor).Out("name").All()
总体的查询模式就是,选顶点,选路径,ALL输出
四. Triple,基于内存的TripleStore数据结构
1.数据结构
type Triple struct {
Subject string
Predicate string
Object string
Provenance string
}
三元组,Provenance好像是类似于数据库里的分库的概念(不大确定),Triple中不同的字段,在后面叫Direction
type TripleStore struct {
idCounter int64 //idMap的长度
tripleIdCounter int64 //tripleId的序列
idMap map[string]int64 //存储三元组的 内容->tripleId 的对应关系
revIdMap map[int64]string //存储三元组的 tripleId->内容 的对应关系 idMap的反向映射关系
triples []graph.Triple //存储每条记录的关系三元组
size int64 //triples的数量
index TripleDirectionIndex //triples的索引 每个idMap中的一个key有一个平衡二叉树,里面放了tripleId
}
TripleDirectionIndex是一个通过Direction作为分组的一级索引
type TripleDirectionIndex struct {
subject map[int64]*llrb.LLRB
predicate map[int64]*llrb.LLRB
object map[int64]*llrb.LLRB
provenance map[int64]*llrb.LLRB
}
2.实例演示
数据
alice follows bob .
bob follows alice .
charlie follows bob .
建立以后的结果如下
idMap revIdMap
1 <=============> alice
2 <=============> follows
3 <=============> bob
4 <=============> charlie
triples
Direction DirectionSubject DirectionPredicate DirectionObject
tripleId 1 alice follows bob
2 bob follows alice
3 charlie follows bob
DirectionIndex
1 =========> (1)
DirectionSubject=============> 3 =========> (2)
4 =========> (3)
DirectionPredicate============> 2 =========> 插入第一行时(1) ---> 插入第二行 (2) /
(1)
-----> 插入第三行 (2)
/ \
(1) (3)
DirectionObject==============> 3 ============> 插入第一行 (1) ---> 插入第三行 (3)
/
(1)
1 =============> (2)
DirectionIndex中的1 是IdMap中的编号,(1)是triples中的tripleId
3.查询方法
看源码里把查询逻辑都写在了itorator里,各种hasA,and,or,link!@#!4。
如果查一个值的入度就是先查DirectionObject索引,查出度就查DirectionSubject索引,有路径条件就再在DirectionPredicate里做二分排除掉。
google Cayley图谱数据库初试的更多相关文章
- Google Cayley图数据库使用方法
最近在用Golang做流程引擎,对于流程图的存储,我看到了Google的Cayley图数据库,感觉它可能会比较适合我的应用,于是便拿来用了用. 项目地址在这里:https://github.com/g ...
- Cayley图数据库的简介及使用
图数据库 在如今数据库群雄逐鹿的时代中,非关系型数据库(NoSQL)已经占据了半壁江山,而图数据库(Graph Database)更是攻城略地,成为其中的佼佼者. 所谓图数据库,它应用图理论( ...
- Cayley图数据库的可视化(Visualize)
引入 在文章Cayley图数据库的简介及使用中,我们已经了解了Cayley图数据库的安装.数据导入以及进行查询等. Cayley图数据库是Google开发的开源图数据库,虽然功能还没有Neo4 ...
- Google 分布式关系型数据库 F1
F1是Google开发的分布式关系型数据库,主要服务于Google的广告系统.Google的广告系统以前使用MySQL,广告系统的用户经常需要使用复杂的query和join操作,这就需要设计shard ...
- nopCommerce 数据库初试化及数据操作
系统启动时执行任务:IStartupTask,启动时执行的任务主要是数据库的初始化和加载. IStartupTask调用IEfDataProvider进行数据库的初始化. IEfDataProvide ...
- NopCommerce架构分析之三---数据库初试化及数据操作
系统启动时执行任务:IStartupTask,启动时执行的任务主要是数据库的初始化和加载. IStartupTask调用IEfDataProvider进行数据库的初始化. IEfDataProvide ...
- Atitit 知识图谱的数据来源
Atitit 知识图谱的数据来源 2. 知识图谱的数据来源1 a) 百科类数据2 b) 结构化数据3 c) 半结构化数据挖掘AVP (垂直站点爬虫)3 d) 通过搜索日志(query record ...
- 从零开始山寨Caffe·柒:KV数据库
你说你会关系数据库?你说你会Hadoop? 忘掉它们吧,我们既不需要网络支持,也不需要复杂关系模式,只要读写够快就行. ——论数据存储的本质 浅析数据库技术 内存数据库——STL的map容器 关 ...
- Google Interview University - 坚持完成这套学习手册,你就可以去 Google 面试了
作者:Glowin链接:https://zhuanlan.zhihu.com/p/22881223来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 原文地址:Google ...
随机推荐
- Oracle之UTL_FILE 包用法详解
[转自] http://zhangzhongjie.iteye.com/blog/1903024 UTL_FILE包可以用来读写操作系统上的文本文件,UTL_FILE提供了在客户端(FORM等等)和服 ...
- 对avalonjs的研究
<!DOCTYPE html> <html> <head> <title>第一个avalon项目</title> <meta char ...
- 5.centos7 jenkins安装
1.安装jdk 安装过程请参照,zookeeper 安装中的jdk安装章节 文章地址: 2.安装jenkins 添加Jenkins库到yum库,Jenkins将从这里下载安装. wget -O /et ...
- springboot+Zookeeper+Dubbo入门
最近想学习dubbo,就利用周末写了一个特别简单的demo,不知道有没有用,先记录一下. 1.安装zookeeper并启动(安装看我上一篇博客https://www.cnblogs.com/huang ...
- baidumapapi点线面的绘制已离线化
百度API离线化 baidumapapi2.0商用是要收费的,开发者使用也要申请个Key. 有个项目要用到点线面的绘制功能,在百度的API示例中发现有这样js封装(DrawingManager_min ...
- (转)Shell中获取字符串长度的七种方法
Shell中获取字符串长度的七种方法 原文:http://blog.csdn.net/jerry_1126/article/details/51835119 求字符串操作在shell脚本中很常用,下面 ...
- TOJ 1883 Domino Effect
Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...
- python 对列表去重,并保持列表原来顺序
mailto = ['cc', 'bbbb', 'afa', 'sss', 'bbbb', 'cc', 'shafa'] addr_to = list(set(mailto)) addr_to.sor ...
- .net Ioc 之 Unity 适合刚开始使用
介绍: 首先稍微介绍一下,Unity是微软patterns& practices组用C#实现的轻量级.可扩展的依赖注入容器,可通过代码或xml配置文件来配置对象之间的关系.那么通过一个简单的代 ...
- keepalived+nginx 高可用集群
一.什么是高可用? nginx做负载均衡,能达到分发请求的目的,但是不能很好的避免单点故障. 1.nginx集群单点问题 分发器宕机怎么处理? 假如nginx服务器挂掉了,那么所有的服务也会跟着瘫 ...