Google Cayley圖數據庫使用方法

最近在用Golang作流程引擎,對於流程圖的存儲,我看到了Google的Cayley圖數據庫,感受它可能會比較適合個人應用,因而便拿來用了用.node

項目地址在這裏:https://github.com/google/cayleygit

系統環境 : Windows 7github

1. 安裝web

安裝的過程項目文檔裏寫的很明白,有兩種安裝方式:數據庫

  1. 直接下載二進制版本.解壓到你喜歡的位置.
  2. 從源碼安裝,遵守項目文檔一步一步來便可.

2. 使用數組

安裝完成以後,你會看到一個【cayley.exe】的文件,它就是咱們要用的程序了。網絡

1. 初始化數據庫測試

初始化數據庫要用到的命令是 init ,你可使用兩種方式初始化,一種是命令行,一種是配置文件。google

咱們先來看命令行的形式:spa

  • 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,第四個叫Label(可選),以.結尾。subject和object會轉換成有向圖的頂點,predicate就是邊。label的用法我查了google group,意思是說,你能夠在一個數據庫裏,存多個圖,用label來區分不一樣的圖,可是我沒有找到關於它的用法。

這張圖的關係以下:

其中箭頭指明瞭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文件夾下,還有更多更詳細的說明,感興趣的讀者能夠看一看。

因爲我的水平有限,若是哪裏有錯誤或者你有更好的經驗,歡迎在評論區留言,我會認真和你交流的。謝謝!

相關文章
相關標籤/搜索