寫在前面
- 態度決定高度!讓優秀成為一種習慣!
- 世界上沒有什么事兒是加一次班解決不了的,如果有,就加兩次?。? - -茂強)
前瞻
一說到圖數據庫,大家估計最先想到的是neo4j,不錯,neo4j在圖數據庫中做的是相當成功,但是在你用的時候,你就會考慮其是否開源,是否免費,你要知道,在公司(不是以圖數據作為業務主要驅動的公司)對于你的一個小小的項目,公司給你買一個數據庫,這是不是很扯淡,所以,你就很想知道,是否有開源的圖數據庫,當然有。但是今天我是要說一個個人比較喜歡的圖數據庫,就是cayley,是完全開源的,項目地址是在google旗下
項目地址:https://github.com/cayleygraph/cayley
一步一步的建立起自己的cayley
- 首先你需要下載你所在環境的包
地址:https://github.com/cayleygraph/cayley/releases
選擇你需要的平臺包
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啟動
這樣你就可以在瀏覽器中打開了
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
- Visualize
這里要說明一下,0.6.1版本對于可視化頁面支持有問題,圖形展示不出來,而且query也查不出來數據,不知是否是瀏覽器問題(我的是chrome),但是0.6.0就可以展示。
下邊將用實例介紹如何用cayley做知識圖譜,敬請期待!