天天看點

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

前言

本文由 Nebula Graph 實習生@王傑貢獻。

最近 @Yener 開源了史上最大規模的中文知識圖譜——

OwnThink

(連結:

https://github.com/ownthink/KnowledgeGraphData

),資料量為 1.4 億條。

本文介紹如何将這份資料快速導入圖資料庫 Nebula Graph,全過程大約需要 30 分鐘。

中文知識圖譜 OwnThink 簡介

思知(OwnThink)

知識圖譜是由 Google 在 2012 年提出來的一個概念。主要是用來描述真實世界中存在的各種實體和概念,以及他們之間的關系。在搜尋引擎、問答機器人、知識抽取等多個領域有着諸多應用。

最近 Yener 開源了史上最大規模的中文知識圖譜—— 

),資料量為 1.4 億條。資料以

(實體, 屬性, 值)

 和

(實體, 關系, 實體)

 混合的三元組形式存儲,資料格式為 csv。

可以點選這裡下載下傳:

https://nebula-graph.oss-accelerate.aliyuncs.com/ownthink/kg_v2.tar.gz

檢視原始檔案

由于 ownthink_v2.csv 資料過多,摘錄部分資料為例:

紅色食品,描述,紅色食品是指食品為紅色、橙紅色或棕紅色的食品。
紅色食品,是否含防腐劑,否
紅色食品,主要食用功效,預防感冒,緩解疲勞
紅色食品,用途,增強表皮細胞再生和防止皮膚衰老
大龍湫,描述,雁蕩山景區分散,東起羊角洞,西至鋸闆嶺;南起筋竹溪,北至六坪山。
大龍湫,中文名稱,大龍湫
大龍湫,外文名稱,big dragon autrum
大龍湫,門票價格,50元
大龍湫,著名景點,芙蓉峰
姚明[中國籃球協會主席、中職聯公司董事長],妻子,葉莉           

這裡的

(紅色食品,是否含防腐劑,否)

 就是典型的 

(實體, 屬性, 值)

 形式的三元組資料; 而

(姚明[中國籃球協會主席、中職聯公司董事長],妻子,葉莉)

 是典型的 

(實體, 關系, 實體)

 形式的三元組資料。

Step 1. 資料模組化與清洗準備

模組化

Nebula Graph 是一個開源的分布式圖資料庫(連結:

https://github.com/vesoft-inc/nebula

),相比 Neo4j 來說,它的主要特點是完全的分布式,是以圖資料庫 Nebula Graph 适合處理資料量超過單機的場景。

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

圖資料庫通常支援的資料模型為有向屬性圖(directed property graph)。圖中的每個頂點(vertex)可以用标簽(tag)來表示類型(Neo4j 叫做 Label),頂點和頂點之間的關系用邊(edge)連接配接起來。每種 tag 和 edge 還可以帶有屬性。——然而,這些功能對于知識圖譜的三元組資料沒什麼意義:

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

分析上圖的三元組資料,發現無論是

(實體, 屬性, 值)

 形式的三元組資料,還是

(實體, 關系, 實體)

 形式的三元組資料,每條三元組資料均可以模組化成兩個點和一條邊的形式。前者三元組中的“實體”和“值”模組化為兩個點(起點、終點),“屬性”模組化為一條邊,後者三元組中的兩個“實體”也模組化為兩個點(起點、終點),“關系”模組化為一條邊.

而且,所有的點都是相同類型(取名叫

entity

),隻需要一個屬性(叫

name

 ),所有的邊也都是同一類型(取名叫

relation

),邊上也隻有一個屬性(叫

name

)。

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

比如

(大龍湫,著名景點,芙蓉峰)

 可以表示成下圖這個樣子:

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

資料清洗和預處理

按照前一節的分析,原始的每條三元組資料,還需要清洗轉換為兩個點和一條邊才能變成屬性圖的模型。

下載下傳清洗工具

本文測試的時候,使用的作業系統是 CentOS 7.5,工具由 Golang 語言編寫而成。

你可以在這裡 (連結:

https://github.com/jievince/rdf-converter

) 下載下傳這個簡單的清洗工具源代碼并編譯使用。

該工具會把轉換後的頂點的資料寫入到 vertex.csv 檔案、邊資料寫入到 edge.csv 檔案。

說明:在測試過程中,發現有大量的重複點資料,是以工具裡面也做了去重。完全去重後的點的資料大概是 4600 萬條,完全去重後的邊的資料大概是 1 億 4000 萬條。

清洗完的

vertex.csv

檔案長這樣:

-2469395383949115281,過度包裝
-5567206714840433083,Over  Package
3836323934884101628,有的商品故意增加包裝層數
1185893106173039861,很多采用實木、金屬制品
3455734391170888430,非科學
9183164258636124946,教育
5258679239570815125,成熟市場
-8062106589304861485,"成熟市場是指低增長率,高占有率的市場。"           

說明:每一行是一個頂點,第一列整型

-2469395383949115281

 是頂點的 ID(叫做 

VID

),它是由第二列文字通過

hash

計算出來的,例如 

-2469395383949115281

就是由

std::hash("過度包裝")

計算出來的值。

edge.csv

檔案:

3413383836870836248,-948987595135324087,含義
3413383836870836248,8037179844375033188,定義
3413383836870836248,-2559124418148243756,标簽
3413383836870836248,8108596883039039864,标簽
2587975790775251569,-4666568475926279810,描述
2587975790775251569,2587975790775251569,中文名稱
2587975790775251569,3771551033890875715,外文名稱
2587975790775251569,2900555761857775043,地理位置
2587975790775251569,-1913521037799946160,占地面積
2587975790775251569,-1374607753051283066,開放時間           

說明:第一列是起點的 VID,第二列是終點的 VID,第三列是這條邊的"屬性"或者"描述"。

在本機完全去重的清洗程式運作時間大約是 6 分鐘。

Step 2. Nebula Graph 啟動準備

下載下傳和安裝

登陸 GitHub 後,在這裡 (連結:

https://github.com/vesoft-inc/nebula/actions

) 找到 Nebula 的安裝包。

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

找到你所用系統對應的下載下傳連結:

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

筆者系統是 CentOS 7.5,下載下傳 CentOS 7.5 最新的壓縮包,解壓後能找到 rpm 安裝包

nebula-5ace754.el7-5.x86_64.rpm

,注意

5ace754

是 git commit 号,使用時可能會有所不同。下載下傳好後解壓,輸入下面指令進行安裝,記得替換成新的 git commit:

$ rpm -ivh nebula-5ace754.el7-5.x86_64.rpm           

啟動 Nebula Graph 服務

指令行 CLI

 輸入下面指令啟動服務

$ /usr/local/nebula/scripts/nebula.service start all           

指令執行結果如下:

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

可以執行以下指令檢查服務是否成功啟動

$ /usr/local/nebula/scripts/nebula.service status all           
使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

連接配接 Nebula Graph 服務

輸入下面指令連接配接 Nebula Graph:

$ /usr/local/nebula/bin/nebula -u user -p password           
使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

準備 schema 等中繼資料

Nebula Graph 的使用風格有點接近 MySQL,需要先準備各種元資訊。

建立圖空間 space

create space 的概念接近 MySQL 裡面 create database。在 nebula console 裡面輸入下面這個指令。

nebula> CREATE SPACE test;           

進入 test space

nebula> USE test;           

建立點類型(entity)

nebula> CREATE TAG entity(name string);           

建立邊類型 (relation)

nebula> CREATE EDGE relation(name string);           

最後簡單确認下中繼資料是不是正确。

檢視 entity 标簽的屬性:

nebula> DESCRIBE TAG entity;           

結果如下:

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

檢視 relation 邊類型的屬性:

nebula> DESCRIBE EDGE relation;           
使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

Step 3. 使用 nebula-importer 導入資料

登陸 GitHub 進入 

https://github.com/vesoft-inc/nebula-importer

 ,nebula-importer 這個工具也是 Golang 語言寫的,在這裡下載下傳并編譯源代碼。

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

另外,準備一個 YAML 配置檔案,告訴這個 importer 工具去哪裡找 csv 檔案。(可直接複制下面這段)

version: v1rc1
description: example
clientSettings:
  concurrency: 10 # number of graph clients
  channelBufferSize: 128
  space: test
  connection:
    user: user
    password: password
    address: 127.0.0.1:3699
logPath: ./err/test.log
files:
  - path: ./vertex.csv
    failDataPath: ./err/vertex.csv
    batchSize: 100
    type: csv
    csv:
      withHeader: false
      withLabel: false
    schema:
      type: vertex
      vertex:
        tags:
          - name: entity
            props:
              - name: name
                type: string
  - path: ./edge.csv
    failDataPath: ./err/edge.csv
    batchSize: 100
    type: csv
    csv:
      withHeader: false
      withLabel: false
    schema:
      type: edge
      edge:
        name: relation
        withRanking: false
        props:
          - name: name
            type: string           

說明:測試時候發現 csv 資料檔案中有大量轉義字元 (\) 和換行字元 (\r),nebula-importer 也做了處理。

最後:開始導入資料

go run importer.go --config ./config.yaml           

執行過程如下:

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

可以看到, 本次導入 QPS 大約在 40 w/s。全部導入總耗時大約 15 min。

Step 4. 随便讀點什麼試試

導入完畢後,我們可以使用 Nebula Graph 服務做一些簡單的查詢。回到 Nebula Graph 的

指令行 CLI

 :

$ /usr/local/nebula/bin/nebula -u user -p password           

進入剛才導入的三元組資料的 test 空間:

nebula> USE test;           

現在,我們可以做一些簡單查詢

  • 例 1:與姚明有直接關聯的邊的類型和點的屬性
([email protected]) [test]> GO FROM hash("姚明[中國籃球協會主席、中職聯公司董事長]") OVER relation  YIELD relation.name AS Name, $$.entity.name AS Value;           

執行結果如下:

使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

可以看到:本次查詢傳回 51 條資料,耗時 3 ms 左右;

  • 例2:查詢姚明和其妻子葉莉在三跳之内的所有路徑
([email protected]) [test]> FIND ALL PATH FROM hash("姚明[中國籃球協會主席、中職聯公司董事長]")  TO hash("葉莉") OVER relation UPTO 3 STEPS;            
使用圖資料庫 Nebula Graph 資料導入快速體驗知識圖譜 OwnThink

當資料量較大時,查找全路徑/最短經之類的操作會比較耗時。可以看到:本次查詢傳回 8 條資料,說明姚明和其妻子葉莉在三跳之内共有 8 條直接或間接的關系。

總結

本篇文章涉及到的一些概念和連結:

  • OwnThink 的中文知識圖譜資料: 。它的資料以三元組形式儲存為 csv
  • Nebula Graph 是一個開源的圖資料庫,GitHub 位址: ,和 Neo4j 相比,它是分布式的
  • 資料清洗工具,GitHub 位址: 。因為原始的圖譜 ownthink_v2.csv 資料以三元組形式儲存,并和一般圖資料庫的屬性圖模型略微有些不同,是以寫了一個 Go 語言工具将原始 ownthink_v2.csv 變成 vertex.csv 和 edge.csv
  • 資料導入工具,GitHub 位址: 。将清洗完的 vertex.csv 和 edge.csv 批量寫入到 Nebula Graph。

後面的工作

  • 調整 Nebula 的參數。似乎預設的日志級别和記憶體都不是很好,可以用下面這個指令關閉日志,這樣導入性能可以好很多。
curl "http://127.0.0.1:12000/set_flags?flag=minloglevel&value=4"           
  • 寫個對應的 Python 版本示例

附錄

Nebula Graph GitHub 位址:

  ,加入 Nebula Graph 交流群,請聯系 Nebula Graph 官方小助手微信号:NebulaGraphbot

繼續閱讀