Google Cayley图数据库使用方法

最近在用Golang做流程引擎,对于流程图的存储,我看到了Google的Cayley图数据库,感觉它可能会比较适合我的应用,于是便拿来用了用.

项目地址在这里:https://github.com/google/cayley

系统环境 : Windows 7

1. 安装

安装的过程项目文档里写的很明白,有两种安装方式:

  1. 直接下载二进制版本.解压到你喜欢的位置.
  2. 从源码安装,遵照项目文档一步一步来即可.

2. 使用

安装完成之后,你会看到一个【cayley.exe】的文件,它就是我们要用的程序了。

1. 初始化数据库

初始化数据库要用到的命令是 init ,你可以使用两种方式初始化,一种是命令行,一种是配置文件。

我们先来看命令行的形式:

  • leveldb : cayley.exe init --db=leveldb --dbpath=tmp/testdb —— 你存储数据的目录就是【tmp/testdb】,它会在这个目录下,建立leveldb数据库;
  • bolt : cayley.exe init --db=bolt --dbpath=tmp/testdb —— 你存储数据的文件名是【tmp/testdb】,它会在【tmp】目录下,创建一个叫做【testdb】的bolt数据库文件;
  • mongo : cayley.exe init --db=mongo --dbpath=”<HOSTNAME>:<PORT>” —— HOSTNAME和PORT指向你的Mongo实例。

在命令行中,--db 和 --dbpath 必须是一起出现的。如果你觉得输入命令行很麻烦,那么可以使用配置文件来初始化。cayley给了一个示例文件【cayley.cfg.example】:

{
"database": "bolt",
"db_path": "/tmp/demodb",
"read_only": false
}

这个使用的是bolt数据库,同时配置了路径以及是否只读。关于配置文件如何配置,等一下我们再说。对我来说,只需要把这个文件改动一下,就可以为我所用了:

{
"database": "bolt",
"db_path": "tmp/testdb", // 我是在【cayley.exe】所在目录下的【tmp】文件夹里创建的数据库文件
"read_only": false
}

2. 向数据库加载数据

数据库初始化好了之后,我们就可以加载数据了。cayley项目里给我们提供了两个测试数据,都在【data】目录下,一个是【testdata.nq】,它是一个简单的基于好友关注的网络图,一个是【30kmoviedata.nq.gz】,这里存储了30k个电影数据信息。我们先用简单的【testdata.nq】。

加载数据要用到 load 命令:

cayley.exe load --config=cayley.cfg.example --quads=data/testdata.nq

这样,就把【testdata.nq】里的数据,加载到数据库里了。

3. 连接你的图数据

加载数据之后,我们就可以查看我们的图了。cayley提供了两种方式,一种是REPL,一种是HTTP。

先说REPL:

cayley.exe repl --config=cayley.cfg.example

这样,cayley就已经跑起来了,你可以看到命令行已经变成“cayley>”等待你的输入了。

再说HTTP:

cayley.exe http --config=cayley.cfg.example

敲完这行命令之后,你会看到控制台输出“Cayley now listening on 127.0.0.1:64210”,接下来只要访问http://127.0.0.1:64210/就能看到它的web界面了。

4. 使用

在使用之前,我们先来看一看,cayley里的数据,是什么样的。比如以【testdata.nq】为例:

 1 <alice> <follows> <bob> .
 2 <bob> <follows> <fred> .
 3 <bob> <status> "cool_person" .
 4 <charlie> <follows> <bob> .
 5 <charlie> <follows> <dani> .
 6 <dani> <follows> <bob> .
 7 <dani> <follows> <greg> .
 8 <dani> <status> "cool_person" .
 9 <emily> <follows> <fred> .
10 <fred> <follows> <greg> .
11 <greg> <status> "cool_person" .

它是由一条条三元组构成,其中第一个叫subject,第二个叫predicate,第三个叫object,以.结束。subject和object会转换成有向图的顶点,predicate就是边。

这张图的关系如下:

其中箭头指明了follows的关系,而#括起来的人名表示,这些人有status为cool_person。

下来我们来看对cayley数据库的增删查:

1 cayley> :a 

subject

 predicate object label .

比如我要添加一个人叫“leon”,他关注了“alice”,并且他也是一个“cool_person”,那么输入这样的命令即可:

1 cayley> :a leon follows alice .
2 cayley> :a leon status cool_person .
1 cayley> :d subject predicate object .

比如我刚才添加的“leon”,现在他不想关注“alice”了,那么这样就可以删除刚才建立的关系了:

1 cayley> :d leon follows alice .

对于查询,cayley提供了两种查询语言,一种是类似于JavaScript的语言,一种是简化的MQL。这里我选用类JavaScript的查询语言。因为它的文档相对完整一些。我会通过介绍对象的方式,把查询方法逐一阐述。

1. graph 对象,简写为 g ,它的存在是唯一的,由它来产生 query 对象,进而返回各种查询结果。它可执行的方法如下所示:

graph.Vertex([nodeId],[nodeId]…) 简写为 g.V

参数:nodeId(可选):一个字符串,或者字符串列表,代表了查询的起始节点

返回:query 对象

从给定的顶点(集)开始一个查询路径,如果没有参数,则认为是图中所有的顶点。

举例:

1 // 我想看目前图中所有的顶点
2 g.V().All()
3 // 我想获得alice这个节点
4 g.V(“alice”).GetLimit(1)

其中All()方法是query对象的方法,用它可以遍历query对象中,所有的数据。GetLimit(number)也是query对象的方法,它获得迭代集里限定数目的数据。

graph.Morphism() 简写为  g.M()

无参数

返回:path 对象

创建一个态射path对象,它本身是不能被查询的,它定义了一类路径映射,可以存储到变量里,在别的查询语句里使用。具体使用之后介绍。主要是和 path.Follow(),path.FollowR()配合使用。

2. path 对象,它是query对象的父类对象。

path对象由 g.V() 和 g.M() 创建,其中 g.V() 创建了query对象,它是path对象的子类。

我们的查询,主要就是使用这个对象,下面以【testdata.nq】里的数据为例,介绍一下都有哪些查询方法。

path.Out([predicatePath],[tags])

参数:predicatePath(可选)下列其中之一

    • 空或者undifined:所有从这个节点出去的predicate。
    • 一个字符串:从这个节点出去的predicate名字。
    • 字符串列表:从这个节点出去的多个predicate名字。
    • 一个query path对象:

  tags(可选)下列其中之一

    • 空或者undifined:没有tags
    • 一个字符串:向输出集使用的指明predicate的标签
    • 字符串列表:添加多个tags

这个方法从path对象开始,通过predicate指向其他objects,也就是要查询的数据。

举例:

 1 // 查看charlie follows了谁。结果是 bob and dani
 2 g.V("charlie").Out("follows")
 3 // 查看alice follows的人,他们又follows了谁。结果是 fred
 4 g.V("alice").Out("follows").Out("follows")
 5 // 从dani出去的路径都指向了哪里。 结果是 bob, greg 和 cool_person
 6 g.V("dani").Out()
 7 // 找到所有dani通过follows和status指向的节点。
 8 // 结果是 bob, greg 和 cool_person
 9 g.V("dani").Out(["follows", "status"])
10 // 找到所有dani通过status指向的节点,并加上tag。
11 // 结果是 {"id": cool_person, "pred": "status"}
12 g.V("dani").Out(g.V("status"), "pred")

path.In([predicatePath],[tags])

和path.Out()用法想同,只不过path.In()查询的是入度,path.Out()查询的是出度。

path.Both([predicatePath],[tags])

用法同上,既查询入度也查询出度。项目文档里说目前这个方法的效率相对来说比较低,因为它是通过Or方法实现的。但是在需要的情况下,还是很有用的。

path.Is(node,[node..])

参数:node:一个或者多个node。

过滤出所有指向参数节点的路径。

举例:

1 // 从图中所有节点出发,找到follows指向bob的路径
2 // 结果显示三个路径指向bob (来自 alice, charlie and dani)
3 g.V().Out("follows").Is("bob")

path.Has(predicate,object)

参数:predicate:指明predicate,也就是哪类路径。

  object:指向的节点

过滤出所有通过predicate指向object的节点

举例:

1 // 从所有节点开始,找到谁follows了。结果是 alice, charlie and dani
2 g.V().Has("follows", "bob")
3 // follows charlie的人之中,哪些人follows了fred。结果是 bob
4 g.V("charlie").Out("follows").Has("follows", "fred")

Tagging

path.Tag(tag) 简写为 path.As

参数:tag:为结果集的key赋予一个字符串。

为了保存你的工作,或者了解路径是怎么到达终点的,cayley提供了tags。

举例:

1 // 从所有节点开始,把他们保存到“start”中,找到所有有status的predicate,并返回结果
2 // 结果是 {"id": "cool_person", "start": "bob"}, {"id": "cool_person", "start": "greg"}, {"id": "cool_person", "start": "dani"}
3 g.V().Tag("start").Out("status")

path.Back(tag)

参数:tag:要跳回的在query里保存的之前的tag名

举例:

1 // 从所有节点出发,把它们保存到“start”中,找到有status的predicate的连接,然后跳回到“start”中,看看有谁follows了他们,返回结果
2 // 结果是:
3 //   {"id": "alice", "start": "bob"},
4 //   {"id": "charlie", "start": "bob"},
5 //   {"id": "dani", "start": "bob"},
6 //   {"id": "charlie", "start": "dani"},
7 //   {"id": "dani", "start": "greg"}
8 g.V().Tag("start").Out("status").Back("start").In("follows")

path.Save(predicate,tag)

参数:predicate:predicate名

  tag:一个tag名用来保存object节点

从当前节点开始作为subject,把它通过predicate连接的节点保存在key为tag指向的value里。

举例:

1 // 从 dani 和 bob 开始,查看他们follows了谁,并把结果保存在 “target”中
2 // 结果:
3 //   {"id" : "dani", "target": "bob" },
4 //   {"id" : "dani", "target": "greg" },
5 //   {"id" : "bob", "target": "fred" },
6 g.V("dani", "bob").Save("follows", "target")

Joining

path.Intersect(query) 简写为 path.And

path.Union(query) 简写为 path.Or

path.Except(query) 简写为 path.Difference

这三个放到一起,就是比较两个path对象中,取交集的数据、取并集的数据和取差集的数据。

参数都只有query对象。

举例:

 1 var cFollows = g.V("charlie").Out("follows")
 2 var dFollows = g.V("dani").Out("follows")
 3 // 1. Intersect
 4 // charlie follows的人 (bob and dani) 和 dani follows的人 (bob and greg) -- 返回 bob
 5 cFollows.Intersect(dFollows)
 6 // 或者相同的方式
 7 g.V("charlie").Out("follows").And(g.V("dani").Out("follows"))
 8 // 2. Union
 9 // charlie (bob and dani) 或 dani (bob and greg) follows的人 -- 返回 bob (来自 charlie), bob (来自 dani), dani and greg.
10 cFollows.Union(dFollows)
11 // 3. Except
12 // 从charlie follows的人中,去掉dani follows的人-- 返回 dani
13 cFollows.Except(dFollows)
14 // 或者相同的方式
15 g.V("charlie").Out("follows").Except(g.V("dani").Out("follows"))

使用 Morphisms

path.Follow(morphism)

path.FollowR(morphism)

这两个放到一起,因为它们都用到了morphism path对象。

参数:morphism:一个态射路径。

有了graph.morphism,我们可以准备一个可复用的path。

  Follow是从morphism定义的路径,顺序查找节点,而FollowR是逆序查找节点的。

举例:

1 friendOfFriend = g.Morphism().Out("follows").Out("follows")
2 // 定义一个morphism为:从给定节点出发,它follows的节点所follows的节点。
3 // 查找charlie follows的人所follows的人里,谁的有status为cool_person
4 // 结果为 bob 和 greg
5 g.V("charlie").Follow(friendOfFriend).Has("status", "cool_person")
6 // 从所有节点出发,找到谁follows的人里,follows了status为cool_person的人
7 // 结果:emily,bob,charlie(来自 bob),charlie(来自greg)
8 g.V().Has("status", "cool_person").FollowR(friendOfFriend)

关于Query对象

query.All()

没有参数,返回值任意。执行结果是query里所有的数据。

query.GetLimit(size)

参数是size,和All()方法一样, 只不过加上了返回结果数量的限制。

query.ToArray()

没有参数,返回一个Array。

query.ToValue()

没有参数,返回一个字符串。和ToArray()方法一样,但是只返回一个结果,就像Limit(1)

query.TagArray()

和ToArray()一样,只不过返回的不是string数组,而是一个键值对数组。

query.TagValue()

和ToValue()一样,返回一个只包含一个tag-to-string的map。

query.ForEach(callback),query.ForEach(limit,callbaack) 简写为 query.Map

略。

关于web界面的可视化

当你使用http界面时,你会看到cayley提供了可视化效果的展示,一种是QueryShape,一种是Visualize。

QueryShape展示了你要查询的态射是什么样的,Visualize会以图形方式展示你的查询结果。在正确地输出图形之前,尤其是Visualize,需要确保查询结果的JSON里,有“target”和“source”这两个键。也就是说,我们在查询的结果里,需要通过Tag,为结果添加标签。

举例:

1 var fOf = g.M().Out("follows").Out("follows").Tag("target")
2 g.V("charlie").Tag("source").Follow(fOf).All()

它返回的结果是这样的JSON,包含了“source”和“target”:

 1 {
 2  "result": [
 3   {
 4    "id": "bob",
 5    "source": "charlie",
 6    "target": "bob"
 7   },
 8   {
 9    "id": "greg",
10    "source": "charlie",
11    "target": "greg"
12   },
13   {
14    "id": "fred",
15    "source": "charlie",
16    "target": "fred"
17   }
18  ]
19 }

这样才能在web页面中,看到可视化的图形展示。

其中QueryShape如下:

Visualize如下:



以上就是我初步尝试cayley数据库的内容,在它项目的doc文件夹下,还有更多更详细的说明,感兴趣的读者可以看一看。

由于个人水平有限,如果哪里有错误或者你有更好的经验,欢迎在评论区留言,我会认真和你交流的。谢谢!

时间: 2024-11-07 01:38:59

Google Cayley图数据库使用方法的相关文章

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&q

图数据库cayley+mongo的起航之旅

图数据库,目前比较主流的可能是Neo4j以及cayley了.但是,由于Neo4j只有社区版是免费的,所以,选择cayley作为项目的最终选择! 今天就简单的介绍下,我的起航之旅. 1.安装go语言环境 去官方地址https://golang.org/dl/,下载稳定版本https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz解压,并将其配置到环境变量. [[email protected] tkrobot]# tar -C

使用neo4j图数据库的import工具导入数据 -方法和注意事项

背景 最近我在尝试存储知识图谱的过程中,接触到了Neo4j图数据库,这里我摘取了一段Neo4j的简介: Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中.它是一个嵌入式的.基于磁盘的.具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中.Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性.程序员工作在一个面向对象的.灵活的网络结构下而不是严格.静态的表中--但是他们可以享受到具备完全的事务

越来越火的图数据库究竟是什么?

随着社交.电商.金融.零售.物联网等行业的快速发展,现实社会织起了了一张庞大而复杂的关系网,传统数据库很难处理关系运算.大数据行业需要处理的数据之间的关系随数据量呈几何级数增长,亟需一种支持海量复杂数据关系运算的数据库,图数据库应运而生. 世界上很多著名的公司都在使用图数据库.比如: 社交领域:Facebook, Twitter,Linkedin用它来管理社交关系,实现好友推荐 零售领域:eBay,沃尔玛使用它实现商品实时推荐,给买家更好的购物体验 金融领域:摩根大通,花旗和瑞银等银行在用图数据

neo4j 图数据库安装及介绍

neo4j 图数据库安装及介绍 一.neo4j图数据库介绍 图数据库,顾名思义就是利用了"图的数据结构来作为数据存储逻辑体现的一种数据库",所以要想学好图数据库当然需要了解一些关于图数据结构的算法!同样的作为图数据结构中很多常用的算法在图数据库中是默认提供支持的,对数据进行查询.计算的操作,比如常见的最短路径算法.pagerank算法等等这些算法,都是图数据结构中常见的算法!当然了neo4j作为一个图数据库当然也会提供这些算法的实现,方便使用者对数据进行操作! 那么图数据结构具体又包含

PHP连接MSSQL数据库的方法,PHPWAMP如何连接MSSQL数据库(极度详细)

最近有用户在使用PHPWAMP的时候,向我咨询一个问题,就是关于PHP如何连接MSSQL数据库. 平时我们搭建网站通常是PHP+Mysql数据库, 不过在项目中,我们有时候必须要用到PHP+MSSQL数据库,那应该怎么办呢? 其实你平时只要多逛逛微软的网站,多看看数据库相关的英文文档,该有的都有, 好了,我们下面演示几个案例吧,分别演示几个主流PHP版本连接MSSQL数据库的方法. 本文演示的是我自己制作的PHP纯绿色集成环境,要是你用的是其他集成环境,或者是自己独立安装的,其实道理是一样的,没

大数据图数据库之TAO数据库

节选自<大数据日知录:架构与算法>十四章 14.1.2  TAO图数据库 Facebook是目前世界上最著名的社交网站,如果从数据抽象的角度来看,Facebook的社交图不仅包括好友之间的关系,还包括人与实体以及实体与实体之间的关系,每个用户.每个页面.每张图片.每个应用.每个地点以及每个评论都可以作为独立的实体,用户喜欢某个页面则建立了用户和页面之间的关系,用户在某个地点签到则建立了用户和地点之间的关系--如果将每个实体看作是图中的节点,实体之间的关系看作是图中的有向边,则Facebook的

基于多种转换语义的图数据库查询

1. 摘要 因为图数据库的复杂模式和不同的信息描写叙述方式,对于非专业用户来说查询复杂的图数据库是异常困难的. 一个好的图查询引擎应该支持多种转化--同义词.缩略词.简写以及本体等等,而且应该可以对搜索结果进行一个非常好地排序. 基于此问题本文提出了一种新型的查询框架来方便用户查询,解放了为构造查询图而抓耳挠腮的用户群. 2. 应用背景 2.1 应用 图数据库也是一种流行的数据存储方式.如知识图.信息网络以及社交网络等应用的数据都存储在图数据库中.由于图数据的无模式或者模式太复杂以及信息的多种描

Neo4j图数据库管理系统开发笔记之三:构建安全的RMI Service(Server)

RMI Server(服务端)主要包括以下功能:远程用户权限验证管理.远程服务接口实现类.Neo4j实体映射转换等.项目目录结构如下图所示: 3.2.1 远程用户权限验证管理 3.2.1.1 用户权限验证机制 用户权限验证机制分为三个层级. 第一级,远程主机IP地址验证.检查是否允许远程主机IP地址访问RMI服务. 第二级,远程用户信息验证.检查用户名称和密码是否正确,用户是否启用等. 第三级,远程服务及接口方法验证.检查用户是否有权访问某个RMI服务以及服务下的指定接口方法. 3.2.1.2