cayley图数据库

写在前面

  • 态度决定高度!让优秀成为一种习惯!
  • 世界上没有什么事儿是加一次班解决不了的,如果有,就加两次!(- - -茂强)

前瞻

一说到图数据库,大家估计最先想到的是neo4j,不错,neo4j在图数据库中做的是相当成功,但是在你用的时候,你就会考虑其是否开源,是否免费,你要知道,在公司(不是以图数据作为业务主要驱动的公司)对于你的一个小小的项目,公司给你买一个数据库,这是不是很扯淡,所以,你就很想知道,是否有开源的图数据库,当然有。但是今天我是要说一个个人比较喜欢的图数据库,就是cayley,是完全开源的,项目地址是在google旗下
项目地址:https://github.com/cayleygraph/cayley

cayley

一步一步的建立起自己的cayley

我是windows测试的,所以就选了windows包
当然你也可以选择源码,进行自行编译部署
mkdir -p ~/cayley && cd ~/cayley
export GOPATH=pwd
export PATH=$PATH:~/cayley/bin
mkdir -p bin pkg src/github.com/cayleygraph
cd src/github.com/cayleygraph
git clone https://github.com/cayleygraph/cayley
cd cayley
curl https://glide.sh/get | sh
glide install
go build ./cmd/cayley
编译好了就可以测试一下,切换到命令目录
./cayley repl -i data/testdata.nq
当然也可以用http模式
./cayley http -i data/testdata.nq

  • 解压文件夹到指定目录(自己指定)
    找到加压后文件夹中的cayley.exe,这个就是我们需要操作的对象,
    通过官方我们知道cayley需要指定(依赖)三方数据库,如:
    KVs: Bolt, LevelDB
    NoSQL: MongoDB
    SQL: PostgreSQL, CockroachDB, MySQL
    n-memory, ephemeral
    这里我们选择levelDB
  • 把cayley.cfg.example文件重命名为cayley.cfg
    这一步可以不用,因为不影响,我个人比较喜欢标准一点,所以就改了
  • cayley.cfg内容配置
    {
    "database": "leveldb",
    "db_path": "d:/cayley/cayley_db",
    "read_only": false
    }
    这里db_path就是cayley需要创建的levelDB的路径,其他的都是字面意思,如果你想依赖起的数据库,比如 Bolt数据库你可以用一下的配置
    {
    "database": "bolt",
    "db_path": "/tmp/demodb",
    "read_only": false
    }
    更多的配置信息:https://github.com/cayleygraph/cayley/blob/master/docs/Configuration.md
  • 初始化cayley依赖的levelDB
    我们在cmd里边切换到cayley.exe所在的文件夹下
    执行命令:
    cayley.exe init --config=cayley.cfg
    或者用:
    cayley.exe init --db=leveldb --dbpath=d:/cayley/cayley_db
    都可以,这样cayley就会在d:/cayley/cayley_db下初始化一个levelDB数据库了,不信你去文件夹下看看
    当然,你也许会用到其他的数据库,比如 Bolt那你可以用
    cayley.exe init --db=bolt --dbpath=tmp/testdb
    如果是MongoDB那就要用
    cayley.exe init --db=mongo --dbpath=”<HOSTNAME>:<PORT>
    其中,HOSTNAME和PORT指向你的Mongo实例
    依赖的数据库建好了之后,那就给里边添加点数据吧
  • 向cayley里边添加数据
    首先让我们看一下数据的具体格式,在data目录下有个testdata.nq的文本,打开后就是如下的数据
    <alice> <follows> <bob> .
    <bob> <follows> <fred> .
    <bob> <status> "cool_person" .
    <charlie> <follows> <bob> .
    <charlie> <follows> <dani> .
    <dani> <follows> <bob> .
    <dani> <follows> <greg> .
    <dani> <status> "cool_person" .
    <emily> <follows> <fred> .
    <fred> <follows> <greg> .
    <greg> <status> "cool_person" .
    <predicates> <are> <follows> .
    <predicates> <are> <status> .
    <emily> <status> "smart_person" <smart_graph> .
    <greg> <status> "smart_person" <smart_graph> .
    这个就是人的关系数据,第一个是主语subject,第二个是谓语predicate,第三个是宾语object,最后以 . 号结束,其中还有,主题还有一个属性status可以从下图来理解


    关系图(版权归原创)

    图中箭头表示follows的关系,而#括起来的人名表示,这些人有status为cool_person
    下边我们把它加载到我们刚才初始化的levelDB中
    cayley.exe load --config=cayley.cfg --quads=data/testdata.nq
    这样数据就加载到了levelDB中了

  • 启动cayley
    cayley的启动方式有两种,一种是REPL另一种是HTTP
    第一种:REPL
    cayley.exe repl --config=cayley.cfg
    启动后是命令行模式


    cayley的repl启动

    第二种:HTTP
    cayley.exe http --config=cayley.cfg
    启动后控制台


    cayley的http启动

    这样你就可以在浏览器中打开了
http模式的界面

cayley的增删查

cayley只有增、删、查,不同于其他的数据库,cayley少了改的操作,其实大家都知道,所谓的改就是先删在增

  • cayley的增
    比如我要添加一个人叫“leon”,他关注了“alice”,并且他也是一个“cool_person”,那么输入这样的命令即可:
    :a leon follows alice .
    :a leon status cool_person .
  • cayley的删
    比如我刚才添加的“leon”,现在他不想关注“alice”了,那么这样就可以删除刚才建立的关系了:
    :d leon follows alice .
  • cayley的查
    cayley的查提供了两种形式的语言,一种和javascript类似,一种是简化的MQL,这里选择js的查询来阐述一下
    graph对象:graph对象简称g,它是唯一存在的,并由它来说产生query对象,通过query返回各种查询结果,执行方式如下:
    graph.Vertex([nodeId],[nodeId]…) 简写为 g.V
    参数:nodeId(可选):一个字符串,或者字符串列表,代表了查询的起始节点
    返回:query 对象
    从给定的顶点(集)开始一个查询路径,如果没有参数,则认为是图中所有的顶点。
    来看例子:
    g.V().All() //我想看目前图中所有的顶点
    g.V("<alice>").GetLimit(1) //获得alice这个节点
    其中All()方法是query对象的方法,用它可以遍历query对象中,所有的数据。GetLimit(number)也是query对象的方法,它获得迭代集里限定数目的数据。
    getAll

    graph.Morphism() 简写为 g.M()
    无参数
    返回:path对象
    path 对象,它是query对象的父类对象
    path对象由 g.V() 和 g.M() 创建,其中 g.V() 创建了query对象,它是path对象的子类。
    path.Out([predicatePath],[tags])
    参数:predicatePath(可选)下列其中之一
    空或者undifined:所有从这个节点出去的predicate
    一个字符串:从这个节点出去的predicate名字
    字符串列表:从这个节点出去的多个predicate名字
    一个query path 对象: 该对象指向一个predicate集合(跟随者)
    tags(可选参数):下列其中之一
    空或者undifined:没有tags
    一个字符串:向输出集使用的指明predicate的标签
    字符串列表:添加多个tags,这些tags当作keys保存指向输出集的predicate
    例子:
    // 查看charlie follows了谁。结果是 bob and dani
    g.V("<charlie>").Out("<follows>").All()
    // 查看alice follows的人,他们又follows了谁。结果是 fred
    g.V("<alice>").Out("<follows>").Out("<follows>").All()
    // 从dani出去的路径都指向了哪里。 结果是 bob, greg 和 cool_person
    g.V("<dani>").Out().All()
    // 找到所有dani通过follows和status指向的节点。
    // 结果是 bob, greg 和 cool_person
    g.V("<dani>").Out(["<follows>", "<status>"]).All()
    // 找到所有dani通过status指向的节点,并加上tag。
    // 结果是 {"id": cool_person, "pred": "status"}
    g.V("<dani>").Out(g.V("<status>"), "pred").All()
    path.In([predicatePath],[tags])
    与path.Out()用法上相同,只不过是一个是出,一个是入
    // Find the cool people, bob, dani and greg
    g.V("cool_person").In("<status>").All()
    // Find who follows bob, in this case, alice, charlie, and dani
    g.V("<bob>").In("<follows>").All()
    // Find who follows the people emily follows, namely, bob and emily
    g.V("<emily>").Out("<follows>").In("<follows>").All()
    path.InPredicates()
    获得指向一个节点的一个predicates列表
    // bob only has "<follows>" predicates pointing inward
    // returns "<follows>"
    g.V("<bob>").InPredicates().All()
    path.Both([predicatePath],[tags])
    这个就是in和out的合并,出入同查
    g.V("<fred>").Both("<follows>").All()
    path.Count()
    返回结果总数
    path.Except(path)
    与path.Difference(path)是一样的效果,就是一种排除查询
    var cFollows = g.V("<charlie>").Out("<follows>")var dFollows = g.V("<dani>").Out("<follows>")
    // People followed by both charlie (bob and dani) and dani (bob and greg) -- returns bob.
    cFollows.Except(dFollows).All() // The set (dani) -- what charlie follows that dani does not also follow.
    // Equivalently, g.V("<charlie>").Out("<follows>").Except(g.V("<dani>").Out("<follows>")).All()
    path.Filter(args)
    过滤,可以通过传入区间或者匹配字符串来过滤
    path.Intersect(path)
    求交集
    var cFollows = g.V("<charlie>").Out("<follows>")
    var dFollows = g.V("<dani>").Out("<follows>")
    // People followed by both charlie (bob and dani) and dani (bob and greg) -- returns bob.
    cFollows.Intersect(dFollows).All()
    // Equivalently, g.V("<charlie>").Out("<follows>").And(g.V("<dani>").Out("<follows>")).All()
    其他的查询方法就不多说了,如果想了解去这里看看
    https://github.com/cayleygraph/cayley/blob/master/docs/GizmoAPI.md

关系图可视化

这个需要在http模式

  • Query Shape
query shape
query shape
  • Visualize
visualize
visualize

这里要说明一下,0.6.1版本对于可视化页面支持有问题,图形展示不出来,而且query也查不出来数据,不知是否是浏览器问题(我的是chrome),但是0.6.0就可以展示。
下边将用实例介绍如何用cayley做知识图谱,敬请期待!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,087评论 18 139
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 8,543评论 0 23
  • 我没有勇气提笔写父亲,我的心情万分悲痛,我想在安静的夜晚和您说说话,现在我的泪有一次模糊了双眼,父亲已经成为一个概...
    慧芮阅读 17,405评论 0 2
  • 身边的夫妻是敷欺,不是敷欺的都离婚了。 夫妻关系首先会想到恩爱,恩爱是指心里有对方,看到对方心里有怦然心动的感觉,...
    朵朵颐阅读 571评论 1 4
  • 昨天发了篇和邀请函有关的文章,于是好多小伙伴来私信我 “请问怎么样才可以拿到邀请函啊?” “可以送张票給我吗?” ...
    木易斐然ElvinStarry阅读 3,114评论 0 1