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閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,781評論 18 139
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,692評論 0 23
  • 我沒有勇氣提筆寫父親,我的心情萬分悲痛,我想在安靜的夜晚和您說說話,現在我的淚有一次模糊了雙眼,父親已經成為一個概...
    慧芮閱讀 17,444評論 0 2
  • 身邊的夫妻是敷欺,不是敷欺的都離婚了。 夫妻關系首先會想到恩愛,恩愛是指心里有對方,看到對方心里有怦然心動的感覺,...
    朵朵頤閱讀 676評論 1 4
  • 昨天發了篇和邀請函有關的文章,于是好多小伙伴來私信我 “請問怎么樣才可以拿到邀請函啊?” “可以送張票給我嗎?” ...
    木易斐然ElvinStarry閱讀 3,201評論 0 1