Cayley圖數據庫的簡介及使用
圖數據庫
??在如今數據庫群雄逐鹿的時代中,非關系型數據庫(NoSQL)已經占據了半壁江山,而圖數據庫(Graph Database)更是攻城略地,成為其中的佼佼者。
??所謂圖數據庫,它應用圖理論(Graph Theory)可以存儲實體的相關屬性以及它們之間的關系信息。最常見例子就是社會網絡中人與人之間的關系。相比於關系型數據庫(比如MySQL等),圖數據庫更能勝任這方面的任務。
??圖數據庫現已湧現出許多出眾的軟件,比如筆者寫過的文章Neo4j入門之中國電影票房排行淺析中的Neo4j,Twitter為進行關系數據分析而構建的FlockDB,高度可擴展的分布式圖數據庫JanusGraph以及Google的開源圖數據庫Cayley
??本文將具體介紹Cayley圖數據庫。
Cayley圖數據庫的簡介
??Cayley圖數據庫是 Google 的一個開源圖(Graph)數據庫,其靈感來自於 Freebase 和 Google 的知識圖譜背後的圖數據庫。它采用Go語言編寫而成,運行命令簡單,一般只需要3到4個命令即可。同時,它擁有RESTful API,內建查詢編輯器和可視化界面,支持多種查詢語言,比如JavaScript,MQL等。另外,它還能支持多種後端數據庫儲存,比如MySQL,MongoDB, LevelDB等,性能良好,測試覆蓋率也OK,功能十分豐富且強大。
??當然,對於我們而言,最重要的特性應該是開源。Cayley圖數據庫的官方Github地址為:https://github.com/cayleygraph/cayley 。
安裝及說明
??關於Cayley圖數據庫的安裝,不同的操作系統的安裝方式不一樣。下載的網址為:https://github.com/cayleygraph/cayley/releases, 截圖如下:
讀者可依據自己的電腦系統下載相應的文件,筆者的電腦為Mac,因此選擇cayley_0.7.5_darwin_amd64.tar.gz文件。同時你的電腦上需要安裝一款Cayley用來儲存後臺數據的數據庫,筆者選擇了MongoDB數據庫。
??當然,Cayley還為你提供了完整的使用說明文檔,可以參考網址:https://github.com/cayleygraph/cayley/blob/master/docs/Quickstart-As-Application.md, 它能幫你快速熟悉Cayley的操作,助你快快上手。筆者會用更簡單的方式幫你熟悉該圖數據庫。
數據準備
??為了能夠更好地了解Cayley圖數據庫,我們應該從數據開始一步步地來構建圖數據庫,並實現查詢功能。本文的數據來源於文章Neo4j入門之中國電影票房排行淺析, 其中爬取了中國電影票房信息,如下:
以及每部電影中的主演信息,如下:
得到了兩個表格文件movies.csv和actor.csv,文件的內容如下:
數據準備完畢。如讀者需要下載該數據,可以參考網址:https://github.com/percent4/Neo4j_movie_demo 。
三元組文件
??Cayley數據庫支持三元組文件導入,所謂三元組,指的是主語subject,謂語predicate 以及賓語object,每個三元組為一行。
??Cayley數據庫支持的三元組文件以nq為後綴,每個三元組為一行,主語、謂語、賓語中間用空格分開,同時還需要註意一下事項(筆者親自踩坑的經歷):
- 註意空格,空格是劃分實體的標誌;
- 註意","是關鍵字,也不能在實體中出現;
- 不能在實體中出現換行符(比如\n);
- 不能出現重復的數據(實體重復、三元組重復都不行)。
??接著我們利用Python程序將movies.csv和actors.csv文件處理成三元組。我們抽取的原則如下:
- 電影名,演員名為實體;
- 電影名與電影的關系為ISA,即電影名 ISA Movie;
- 演員名與電影名的關系為ACT_IN,即演員名 ACT_IN 電影名;
- 電影名的其余為屬性對,即電影名 屬性 屬性名, 比如戰狼2 rank 1.
??實現的Python程序如下:
# -*- coding: utf-8 -*-
import pandas as pd
# 讀取文件
movies = pd.read_csv('movies.csv')
actors = pd.read_csv('actors.csv')
# print(movies.head())
# 處理電影數據為三元組,抽取的三運組如下:
# 電影名 ISA Movie
# 電影名 屬性 屬性值
with open('China_Movie.nq', 'w') as f:
name_df = movies['name']
for i in range(name_df.shape[0]):
f.write('<%s> <ISA> <Movie> .\n'%name_df[i])
for col in movies.columns:
if col != 'name':
f.write('<%s> <%s> "%s" .\n'%(name_df[i], col, movies[col][i]))
# 處理演員數據為三元組,抽取的三運組如下:
# 演員名 ISA Actor
# 演員名 ACT_IN 電影名
with open('China_Movie.nq', 'a') as f:
for i in range(actors.shape[0]):
for actor in actors['actors'][i].split(','):
f.write('<%s> <ACT_IN> <%s> .\n' % (actor, actors['name'][i]))
在China_Movie.nq中,共有276個三元組,文件的前幾行如下:
<戰狼2>
.
<戰狼2>"1" .
<戰狼2>"/item/%E6%88%98%E7%8B%BC2" .
<戰狼2>"56.83億" .
<戰狼2> "35" .
<戰狼2> "38" .
<戰狼2>"2017.07.27" .
<流浪地球>.
<流浪地球>"2" .
<流浪地球>"/item/%E6%B5%81%E6%B5%AA%E5%9C%B0%E7%90%83" .
<流浪地球>"40.83億" .
<流浪地球> "46" .
<流浪地球> "50" .
<流浪地球>"2019.02.05" .
<紅海行動>.
導入數據
??將China_Movie.nq文件移動至Cayley的data目錄下,同時配置cayley_example.yml文件,內容如下:
store:
# backend to use
backend: mongo
# address or path for the database
address: "localhost:27017"
# open database in read-only mode
read_only: false
# backend-specific options
options:
nosync: false
query:
timeout: 30s
load:
ignore_duplicates: false
ignore_missing: false
batch: 10000
在該配置文件中,聲明了Cayley的後臺數據庫為MongoDB,同時制定了ip及端口。
??接著運行命令:
./cayley load -c cayley_example.yml -i data/China_Movie.nq
等待數據導入,接著前往MongoDB中查看,如發現MongoDB中存在cayley數據庫,則表明數據導入成功。
使用查詢語句
??接著再輸入命令:
./cayley http -i ./data/China_Movie.nq -d memstore --host=:64210
這樣就支持在瀏覽器中進行查詢了,只需要在瀏覽器中輸入http://localhost:64210/ 即可,界面如下:
??關於查詢語句,它是圖數據庫的精華所在,而對於Cayley而言,它的查詢語句相對來說就比較簡單且好理解,具體的查詢語句命令可以參考官網: https://github.com/cayleygraph/cayley/blob/master/docs/GizmoAPI.md
,本文將通過幾個簡單的查詢語句來說明怎樣對Cayley圖數據庫進行查詢。
查詢一共有多少條數據
命令為:
var n = g.V().Count();
g.Emit(n);
其中g代表圖,V代表頂點,g.Emit()會將結果以JSON格式返回。輸出的結果如下:
{
"result": [
521
]
}
查詢全部電影
命令為:
var movies = g.V('<Movie>').In('<ISA>').ToArray();
g.Emit(movies);
返回的結果如下:
{
"result": [
[
"<戰狼2>",
"<流浪地球>",
"<紅海行動>",
"<唐人街探案2>",
"<美人魚>",
"<我不是藥神>",
"<速度與激情8>",
"<西虹市首富>",
"<捉妖記>",
"<速度與激情7>",
"<復仇者聯盟3:無限戰爭>",
"<捉妖記2>",
"<羞羞的鐵拳>",
"<海王>",
"<變形金剛4:絕跡重生>",
"<前任3:再見前任>",
"<瘋狂的外星人>",
"<毒液:致命守護者>",
"<功夫瑜伽>",
"<侏羅紀世界2>"
]
]
}
查詢電影《流浪地球》的所有屬性值
命令為:
var movie = "<流浪地球>";
var attrs = g.V(movie).OutPredicates().ToArray(); //類型為object,即字典
values = new Array();
for (i in attrs) {
var value = g.V(movie).Out(attrs[i]).ToValue();
values[i] = value;
}
key_val_json = new Object();
for (i in attrs) {
key_val_json[attrs[i]]= values[i];
}
g.Emit(key_val_json)
輸出結果如下:
{
"result": [
{
"<ISA>": "<Movie>",
"<avg_people>": "50",
"<avg_price>": "46",
"<begin_date>": "2019.02.05",
"<box_office>": "40.83億",
"<rank>": "2",
"<src>": "/item/%E6%B5%81%E6%B5%AA%E5%9C%B0%E7%90%83"
}
]
}
查詢沈騰主演的電影
命令為:
var movies = g.V('<沈騰>').Out('<ACT_IN>').ToArray();
g.Emit(movies);
輸出為:
{
"result": [
[
"<西虹市首富>",
"<羞羞的鐵拳>",
"<瘋狂的外星人>"
]
]
}
查詢《捉妖記》與《捉妖記2》的共同演員
命令為:
var actors1 = g.V('<捉妖記>').In('<ACT_IN>');
var actors2 = g.V('<捉妖記2>').In('<ACT_IN>');
var common_actor = actors2.Intersect(actors1).ToArray();//集合交集
g.Emit(common_actor);
輸出為:
{
"result": [
[
"<白百何>",
"<井柏然>",
"<曾誌偉>",
"<吳君如>"
]
]
}
總結
??在本文中,筆者介紹了一種新的圖數據庫Cayley,並介紹了它的安裝方式,以及如何導入三元組數據,進行查詢。希望能夠給讀者一些參考~
??雖然是Google開源的圖數據庫,但在網上關於Cayley圖數據庫的介紹並不多,而且都未能深入地講解,大多是照搬官方文檔的講解,希望筆者的講解能夠帶來一些進步,這也是筆者寫此文的目的。希望此文能多少幫到讀者~
註意:不妨了解下筆者的微信公眾號: Python爬蟲與算法(微信號為:easy_web_scrape), 歡迎大家關註~
Cayley圖數據庫的簡介及使用