|
一般情況下,我們使用數(shù)據(jù)庫查找事物間的聯(lián)系的時候,只需要短程關系的查詢(兩層以內的關聯(lián))。當需要進行更長程的,更廣范圍的關系查詢時,就需要圖數(shù)據(jù)庫的功能。 而隨著社交、電商、金融、零售、物聯(lián)網(wǎng)等行業(yè)的快速發(fā)展,現(xiàn)實世界的事物之間織起了一張巨大復雜的關系網(wǎng),傳統(tǒng)數(shù)據(jù)庫面對這樣復雜關系往往束手無策。因此,圖數(shù)據(jù)庫應運而生。 圖數(shù)據(jù)庫(Graph database)指的是以圖數(shù)據(jù)結構的形式來存儲和查詢數(shù)據(jù)的數(shù)據(jù)庫。 從 http:///en/ranking 可以發(fā)現(xiàn),Neo4j 是目前用的最多的圖數(shù)據(jù)庫,世界數(shù)據(jù)庫排行榜上排名21位。 Neo4J屬于原生圖數(shù)據(jù)庫,其使用的存儲后端專門為圖結構數(shù)據(jù)的存儲和管理進行定制和優(yōu)化的,在圖上互相關聯(lián)的節(jié)點在數(shù)據(jù)庫中的物理地址也指向彼此,因此更能發(fā)揮出圖結構形式數(shù)據(jù)的優(yōu)勢。 知識圖譜中,知識的組織形式采用的就是圖結構,所以非常適合用neo4j進行存儲。 圖數(shù)據(jù)庫的優(yōu)勢在于:
數(shù)據(jù)存儲形式neo4j的數(shù)據(jù)存儲形式 主要是 節(jié)點(node)和 邊(edge) 來組織數(shù)據(jù)。node可以代表知識圖譜中的實體,edge可以用來代表實體間的關系,關系可以有方向,兩端對應開始節(jié)點和結束節(jié)點。 查詢語言cypherneo4j采用自己設計的查詢語言cypher,其特點和sql有很多相似的地方。match、where、return是最常用到的關鍵詞:
安裝neo4j這里我們使用docker安裝neo4j,安裝命令行如下: docker run -d --name=Neo4j\根據(jù)配置參數(shù),我們將容器內的7474端口掛載到外部宿主機的7474端口,并設置好文件夾的映射關系,注意/import文件夾下放的是將要導入數(shù)據(jù)庫的csv文件。 我們通過一個例子來說明如何運用neo4j數(shù)據(jù)庫。 1. 導入數(shù)據(jù)我們這里有兩個csv文件如下圖,左邊的nodes_companies.csv是一部分公司節(jié)點,右邊的edges_director_duration.csv是這些公司互相之間的服務關系。 把這兩個文件放到neo4j根目錄下的import文件夾內,使用LOAD…AS row語句讀取,表示將csv文件按行讀取,每行的變量名為row。再使用MERGE指令創(chuàng)建節(jié)點,將csv文件的第一列數(shù)據(jù)與第二列數(shù)據(jù)匯總為一個結點內的兩條屬性信息。 這里提一下cypher中兩個用于創(chuàng)建新的數(shù)據(jù)的兩個關鍵詞: create 和 merge merge:在數(shù)據(jù)庫中可以匹配到模式相同的數(shù)據(jù)就返回,沒有則創(chuàng)建一條這樣的數(shù)據(jù)(有則返回,沒有則創(chuàng)建) 上面再LOAD文件時使用merge可以避免導入完全重復的數(shù)據(jù)。 通過第二個csv文件的START_ID和END_ID字段為第一個csv文件的company之間建立聯(lián)系,即不斷遍歷第二個文件的每一行,根據(jù)START_ID和END_ID使用where找到圖中相應節(jié)點,并為它們添加相應的服務(INTERLOCK)關系,添加關系屬性為weight。 LOAD CSV WITH HEADERS FROM 'file:///edges_director_duration.csv' AS row注意在cypher語句里,節(jié)點是用()括起來表示,關系則用 [] 括起來表示。 2.創(chuàng)建關系這里我們嘗試自己創(chuàng)建一條新的關系,比如在id = 281 和 id = 879 的兩個節(jié)點間創(chuàng)建一條標簽為“INTERLOCK”的關系。 先match和where鎖定 id = 281 和 id = 879的兩個公司節(jié)點,然后用create創(chuàng)建他們之間的關系,并添加特定關系屬性信息(例如weight為10)。 cypher語句如下: 這條語句的意思是,匹配類別標簽為company,id分別等于281和879的兩個公司節(jié)點,設置變量名為c1和c2,在他們之間創(chuàng)建關系,關系變量名為r,這里 ()-[]-() 代表無向邊,()-[]->() 代表有向邊。 返回結果 (c1)-[r]-(c2) 匹配到的子圖如下所示: 3.比較復雜的查詢下面這條語句會把所有公司中,指向其他公司的連接關系數(shù)超過75條的公司全部找出來。用空括號()代表任一節(jié)點,函數(shù)count() 計算關系的數(shù)量。 MATCH (c:company)-[r:INTERLOCK]->() WITH c, count(r) as relaNum WHERE relaNum>=75 RETURN c,relaNum4.最短路徑查詢neo4j還還內置實現(xiàn)了一套圖搜索算法,并提供了相關函數(shù)接口,比如你想查詢兩個節(jié)點之間的最短路徑,就可以用下面的查詢語句:
直接調用函數(shù)shortestPath,傳入的參數(shù)為選定的關系,選取任意兩個節(jié)點,<>表示id不相等,因為查找的兩個點不能是同一個點,*..10表示10度以內的所有關系,返回降序排序的長度,限制在1000個防止內存溢出)
MATCH (c1:company), (c2:company), p = allshortestpaths((c1)-[r:INTERLOCK*]-(c2))語句中的pathLength是路徑的邊數(shù)(第一句return),pathDist是路徑上所有帶weight邊的加權總和(第二句return)。 |
|
|