1. 程式人生 > >Cayley圖數據庫的簡介及使用

Cayley圖數據庫的簡介及使用

分析 -c asc option 文件導入 後端 微信公眾號 復仇者聯盟 yam

圖數據庫

??在如今數據庫群雄逐鹿的時代中,非關系型數據庫(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圖數據庫。

安裝及說明

??關於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的操作,助你快快上手。筆者會用更簡單的方式幫你熟悉該圖數據庫。

??So, let‘s begin!

數據準備

??為了能夠更好地了解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圖數據庫的簡介及使用