【知识图谱实战】 Neo4j入门与示例
文章目錄
- 一、Neo4j介紹
- 1、安裝Java JRE
- 2、安裝Neo4j
- 二、Cypher基本語句
- 1、基本CQL語句
- 2、MATCH
- 3、Cypher 導入CSV數據
- 三、示例1:藥材供應鏈圖譜實現
- 1、導入數據創建實體
- 2、導入數據創建關系
- (1)示例圖譜
- (2)數據導入與顯示
- 3、完整代碼
- 四、示例2:python與neo4j
- 1、準備工作
- (1)安裝 py2neo
- (2)py2neo連接neo4j
- 2、構建知識圖譜
- (1)清空數據庫結點和邊
- (2)結點創建
- (3)關鍵創建
- 3、完整代碼
- 參考
知識圖譜中的每一條數據或事實一般會采用 <實體,屬性,屬性值>、 <實體, 關系, 實體> 的 三元組形式來表示。Neo4j 是目前最流行的圖形數據庫,支持完整的事務,在屬性圖中,圖是由頂點(Vertex),邊(Edge)和屬性(Property)組成的,頂點和邊都可以設置屬性,頂點也稱作節點,邊也稱作關系,每個節點和關系都可以由一個或多個屬性。Neo4j創建的圖是用頂點和邊構建一個有向圖,其查詢語言cypher已經成為事實上的標準。
Neo4j 圖數據庫安裝初識及藥材供應圖譜實例
一、Neo4j介紹
在安裝neo4j之前,需要安裝Java JRE,并配置Java開發環境,然后安裝neo4j服務。
1、安裝Java JRE
Neo4j是基于Java運行環境的圖形數據庫,因此,必須向系統中安裝JAVA SE(Standard Editon)的JRE。
- JDK和JRE是有區別的:JDK(Java Development Kit)是包括Java運行環境(JRE)和Java開發工具;而JRE(Java Runtime
Environment)是運行Java程序時必須安裝的環境。 - 如果只是運行Java程序,那么只需要安裝JRE即可;如果希望開發Java程序,那么必須安裝JDK。
下載地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html
安裝:正常安裝,省略…
環境配置
- 新建 JAVA_HOME 變量,值為 jdk 的安裝路徑,默認安裝路徑為 C:\Program Files\Java\jdk1.8.0_201
- 編輯Path變量,在Path變量值的最后添加:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
驗證配置是否成功。
- 運行cmd,輸入 java -version,如果顯示java的版本信息,說明Java的安裝和配置成功。
2、安裝Neo4j
下載地址:https://neo4j.com/download-center/
- 該地址包含:企業版、社區版、桌面版
桌面版:比社區版功能多,此處使用桌面版本。
- 直接下載安裝即可。
- 運行軟件并初始化,如下圖所示。
- 成功運行后的軟件如下圖所示。
二、Cypher基本語句
Cypher是 Neo4j 的數據庫語言,既然是數據庫語言,最基本的語句也是增刪改查。
本節關注如何實現基本的增刪改查、導入數據。
更多請移步官網
1、基本CQL語句
--創建節點 CREATE (p:Person { name:"Keanu Reeves", born:1964 }) --創建節點和關系 CREATE (p:Person{name:"kay"})-[:KNOWS]->(:Person{name:"Keanu Reeves"}) return p--查詢 MATCH (p:Person) WHERE p.name="kay" return p --或者 MATCH (p:Person{name:"kay"}) return p --查詢關系路徑 MATCH path=(p:Person{name:"kay"})-[:KNOWS]->(p:Person) return path--修改 MATCH (p:Person) WHERE p.name="kay" set p.name="fen" return p--刪除 MATCH (p:Person) WHERE p.name="kay" delete p--徹底刪除(清空數據庫,包括關系) MATCH (n) DETACH DELETE n示例:
- 知識圖譜創建:創建 2 個 Person節點,一個 Movie節點,建立關系,節點的屬性以鍵值對的形式存儲 {key:value}
- 結果為:
- 查詢
2、MATCH
Match 類似與SQL中的Select ,用來匹配一種搜索模式
查詢所有節點
MATCH (n) RETURN n查詢所有電影 Movie 標簽
MATCH (movie:Moive) RETURN movie.title3、Cypher 導入CSV數據
導入Person數據,新建Person節點:
LOAD CSV WITH HEADERS FROM "https://neo4j.com/docs/developer-manual/3.4/csv/import/persons.csv" AS csvLine CREATE (p:Person { id: toInteger(csvLine.id), name: csvLine.name })person.csv 格式如下:
id,name 1,Charlie Sheen 2,Oliver Stone 3,Michael Douglas 4,Martin Sheen 5,Morgan Freeman如此便導入5個Person節點,Person{id,name},屬性有 id 和 name.
三、示例1:藥材供應鏈圖譜實現
1、導入數據創建實體
步驟如下:
- 點擊 Project,然后點擊 Add Graph ,然后點擊 Create a Local Graph 按鈕,創建一個本地的圖。
- 設置新創建圖的名字及密碼,如 Graph0905、123456,點擊創建。
- 啟動數據庫服務器:點擊 Graph00905 中的 Start 按鈕。
- 運行:點擊 Manage 管理頁面,接著點擊 Open Browser 打開瀏覽器。
2、導入數據創建關系
(1)示例圖譜
假設該藥材的供應鏈如下圖所示,現在需要建立對應的簡單圖譜。
(2)數據導入與顯示
數據傳送門:
鏈接1:https://pan.baidu.com/s/110rgkojcbEPdOzeRBZpeWA
提取碼:sgio
鏈接2:https://download.csdn.net/download/u012736685/11674776
注意:為了防止出現顯示的時候出現中文亂碼,建議采用記事本打開CSV文件,將文件編碼方式從ASC-II修改為UTF-8。
數據顯示(前幾行):
- 企業 entity-01.csvid,name,label 1,威門藥業, 企業 2,東莞焱興實業, 企業 3,銀川塞外杞香, 企業 4,安徽亳州藥業, 企業
- 藥材 entity-02.csvid,name,label 13,北沙參,藥材 14,枸杞子,藥材 15,麥冬,藥材
① 數據集的存放位置:放在該數據庫的 import文件夾 下
- 位置:\Neo4jData\neo4jDatabases\database-d037fa02-eb2c-4b32-964c-8fca89293883\installation-3.5.6\import,需要根據自己情況進行調整。
② 數據導入
導入企業 entity-01.csv 文件:從import文件夾中載入CSV文件,AS line 表示按行讀取文件內容,包括兩個值:id 和 name,抽象的實體概念名字為Enterprise(企業)。
③ 顯示所有實體
顯示結果如下:
同時,可以編輯節點的顏色、大小,顯示指定的雙屬性,如下所示。
④ 導入藥材 entity-02.csv 數據
抽象的實體概念名字為Medicinal(藥材),包括兩個屬性:id 和 name
結果顯示:
⑤ 插入關系,包括三種:
- rela-11.csv:企業與企業的關系,企業買賣交易。
- 數據示例:from_id,pro1,pro2,pro3,pro4,pro5,pro6,pro7,to_id 1,交易,北沙參,威門藥業股份有限公司,東莞市焱興實業發展有限公司,936,10,9360,2 1,交易,枸杞子,威門藥業股份有限公司,銀川塞外杞香科貿有限公司,159,6,954,3 1,交易,麥冬,威門藥業股份有限公司,安徽亳州藥業集團,938,9,8442,4
- 代碼實現:需要注意 from_id(關系起始) 和 to_id(關系介紹),包含的屬性需要和CSV表格一致。LOAD CSV WITH HEADERS FROM "file:///rela-11.csv" AS line match (from:Enterprise{id:line.from_id}),(to:Enterprise{id:line.to_id}) merge (from)-[r:rel{pro1:line.pro1,pro2:line.pro2,pro3:line.pro3,pro4:line.pro4,pro5:line.pro5,pro6:line.pro6,pro7:line.pro7}]->(to)
- 顯示:企業之間交易關系match(n) return n
- rela-12.csv:企業與藥品的關系,威門藥業購入藥品。
- 數據示例:from_id,pro1,pro2,pro3,pro4,to_id 1,買入,藥品,威門藥業股份有限公司,東莞市焱興實業發展有限公司,13 1,買入,藥品,威門藥業股份有限公司,銀川塞外杞香科貿有限公司,14 1,買入,藥品,威門藥業股份有限公司,安徽亳州藥業集團,15 1,買入,藥品,威門藥業股份有限公司,安徽亳州藥業集團,16
- 代碼實現LOAD CSV WITH HEADERS FROM "file:///rela-12.csv" AS line match (from:Enterprise{id:line.from_id}),(to:Medicinal{id:line.to_id}) merge (from)-[r:rel{pro1:line.pro1,pro2:line.pro2,pro3:line.pro3,pro4:line.pro4}]->(to)
- 顯示:企業藥材之間關系match(n) return n
- rela-21.csv:企業與藥品的關系,from_id企業賣出to_id藥品。
- 數據示例:from_id,pro1,pro2,to_id 2,藥品,賣出,13 3,藥品,賣出,14 4,藥品,賣出,15
- 代碼實現LOAD CSV WITH HEADERS FROM "file:///rela-21.csv" AS line match (from:Enterprise{id:line.from_id}),(to:Medicinal{id:line.to_id}) merge (from)-[r:賣出{pro1:line.pro1,pro2:line.pro2}]->(to)
- 顯示:企業藥材之間關系match(n) return n
⑥ 獲取實體關系的頂層概念關系。
3、完整代碼
--載入實體 LOAD CSV WITH HEADERS FROM "file:///entity-01.csv" AS line MERGE (p:Enterprise{id:line.id,name:line.name}) LOAD CSV WITH HEADERS FROM "file:///entity-02.csv" AS line MERGE (p:Medicinal{id:line.id,name:line.name})--顯示節點 match(n) return n match(n) return n limit 9--刪除節點及關系 MATCH (n)-[r]-() DELETE n,r match(n) return n--刪除關系 MATCH (n)-[r]-() DELETE r--單純刪除所以節點: match (n) delete n--查詢指定節點 match (tom {id: "1"}) return tom--載入關系1 LOAD CSV WITH HEADERS FROM "file:///rela-11.csv" AS line match (from:Enterprise{id:line.from_id}),(to:Enterprise{id:line.to_id}) merge (from)-[r:rel{pro1:line.pro1,pro2:line.pro2,pro3:line.pro3,pro4:line.pro4,pro5:line.pro5,pro6:line.pro6,pro7:line.pro7}]->(to)match(n) return n--載入關系2 LOAD CSV WITH HEADERS FROM "file:///rela-12.csv" AS line match (from:Enterprise{id:line.from_id}),(to:Medicinal{id:line.to_id}) merge (from)-[r:rel{pro1:line.pro1,pro2:line.pro2,pro3:line.pro3,pro4:line.pro4}]->(to)match(n) return n--載入關系3 LOAD CSV WITH HEADERS FROM "file:///rela-21.csv" AS line match (from:Enterprise{id:line.from_id}),(to:Medicinal{id:line.to_id}) merge (from)-[r:賣出{pro1:line.pro1,pro2:line.pro2}]->(to)MATCH p=()-[r:`賣出`]->() RETURN p LIMIT 25 match(n) return n--顯示頂層概念 call db.schema四、示例2:python與neo4j
官方文檔:https://py2neo.org/v3/index.html
1、準備工作
(1)安裝 py2neo
pip install py2neo(2)py2neo連接neo4j
def __init__(self):# 建立連接link = Graph("http://localhost:7474", username = "neo4j", password = "123456")self.graph = link報錯:ProtocolError: Server certificate does not match known certificate for ‘localhost’; check details in file ‘C:\Users\XXXXX\.neo4j\known_hosts’
解決方法:清空 “knonw_hosts” 文件中的內容
2、構建知識圖譜
(1)清空數據庫結點和邊
def clean_node(self):# 清空數據庫self.graph.delete_all()(2)結點創建
class Node(*labels, **properties) 定義中 label 的理解:標記一簇結點的信息。
from py2neo import Node def create_node(self):# 疾病、臨床表現、藥物等結點定義for each_dis in dis_list:dis_node=Node(dis_label,name=each_dis)self.graph.create(dis_node)for each_cli in cli_list:cli_node = Node(cli_label, name=each_cli)self.graph.create(cli_node)for each_sdef in drug_list:drug_node = Node(dru_label, name=each_sdef)self.graph.create(drug_node)for each_sdef in sdef_list:sdef_node=Node(side_effect_label,name=each_sdef)self.graph.create(sdef_node)for each_zd in zd_method_list:zd_node=Node(diagnostic_label,name=each_zd)self.graph.create(zd_node)(3)關鍵創建
選取結點:使用 find_one() 方法,通過指定 label,property_key,property_value 獲取相應的結點。示例如下所示。
hyp = self.graph.find_one(label = dis_label,property_key = "name",property_value = "高血壓" )結點關系方法封裝
from py2neo import Relationship def create_Rel(self):"""建立關系高血壓疾病與臨床表現之間的雙向關系定義:return:"""# 獲取高血壓與糖尿病結點,然后通過循環,建立這兩個疾病與臨床表現的關系hyp_node = self.graph.find_one(label=dis_label,property_key="name",property_value="高血壓")tnb_node = self.graph.find_one(label=dis_label,property_key="name",property_value="糖尿病")# 建立疾病與臨床表現的關系for cli_name in cli_list:cli_node = self.graph.find_one(label=cli_label,property_key="name",property_value=cli_name)hyp_to_cli = Relationship(hyp_node, '產生', cli_node)self.graph.create(hyp_to_cli)tnb_to_cli = Relationship(tnb_node, '產生', cli_node)self.graph.create(tnb_to_cli)# 建立疾病與診斷方法之間的關系for diag_name in zd_method_list:diag_node = self.graph.find_one(label=diagnostic_label,property_key="name",property_value=diag_name)if diag_name=="血糖" and diag_name=="血脂" and diag_name=="膽固醇":diag_to_dis = Relationship(diag_node, '輔助檢查', tnb_node)else:diag_to_dis = Relationship(diag_node, '輔助檢查', hyp_node)self.graph.create(diag_to_dis)# 建立疾病與藥物關系for drug_name in drug_list:drug_node = self.graph.find_one(label=dru_label,property_key="name",property_value=drug_name)if drug_name=="胰島素" or drug_name=="胰高血糖素":drug_to_disease=Relationship(drug_node,'治療',tnb_node)else:drug_to_disease= Relationship(drug_node, '治療', hyp_node)self.graph.create(drug_to_disease)# 建立藥物與副作用之間的關系for drug_name in drug_list:drug_node = self.graph.find_one(label=dru_label,property_key="name",property_value=drug_name)for sdef_name in sdef_list:sdef_node = self.graph.find_one(label=side_effect_label,property_key="name",property_value=sdef_name)if drug_name == "利尿藥" and sdef_name == "尿酸升高":drug_to_sdef = Relationship(drug_node, '引發', sdef_node)self.graph.create(drug_to_sdef)elif drug_name == "鈣拮抗藥" and sdef_name == "血鉀降低":drug_to_sdef = Relationship(drug_node, '引發', sdef_node)self.graph.create(drug_to_sdef)elif drug_name == "胰島素" and (sdef_name == "惡心" or sdef_name == "嘔吐"):drug_to_sdef = Relationship(drug_node, '引發', sdef_node)self.graph.create(drug_to_sdef)elif drug_name == "胰高血糖素" and (sdef_name == "頭暈" or sdef_name == "眼花"):drug_to_sdef = Relationship(drug_node, '引發', sdef_node)self.graph.create(drug_to_sdef)3、完整代碼
# -*- coding: utf-8 -*- """ Created on Fri Sep 6 13:47:39 2019@author: 杰 """ from py2neo import Graph,Node,Relationship #,NodeSelector# 疾病 dis_list = ["糖尿病", "高血壓"] # 臨床表現 cli_list = ["腎臟損害", "心臟損害", "腦部損害", "大小動脈損害"] # 藥物 drug_list = ["利尿藥", "鈣拮抗藥", "胰島素", "胰高血糖素"] # 診斷方法 zd_method_list = ["血脂", "血糖", "膽固醇", "超聲心動圖", "心電圖", "肝功能", "腎功能"] # 副作用 sdef_list = ["惡心", "嘔吐", "頭暈", "眼花","血鉀降低","尿酸升高"] # 定義三個label dis_label = "疾病" # 定義疾病label cli_label = "臨床表現" # 定義臨床表現label dru_label = "藥物" # 定義藥物label side_effect_label = "副作用"# 定義副作用label diagnostic_label = "診斷方法"# 定義診斷label class createBHPData(object):def __init__(self):# 建立連接link = Graph("http://localhost:7474", username="neo4j", password="123456")self.graph = linkdef clean_node(self):# 清空數據庫self.graph.delete_all()def create_node(self):# 疾病、臨床表現、藥物等結點定義for each_dis in dis_list:dis_node = Node(dis_label,name=each_dis)self.graph.create(dis_node)for each_cli in cli_list:cli_node = Node(cli_label, name=each_cli)self.graph.create(cli_node)for each_sdef in drug_list:drug_node = Node(dru_label, name=each_sdef)self.graph.create(drug_node)for each_sdef in sdef_list:sdef_node = Node(side_effect_label,name=each_sdef)self.graph.create(sdef_node)for each_zd in zd_method_list:zd_node = Node(diagnostic_label,name=each_zd)self.graph.create(zd_node)def create_Rel(self):"""建立關系高血壓疾病與臨床表現之間的雙向關系定義:return:"""# 獲取高血壓與糖尿病結點,然后通過循環,建立這兩個疾病與臨床表現的關系hyp_node = self.graph.find_one(label = dis_label,property_key = "name",property_value = "高血壓")tnb_node = self.graph.find_one(label = dis_label,property_key = "name",property_value = "糖尿病")# 建立疾病與臨床表現的關系for cli_name in cli_list:cli_node = self.graph.find_one(label=cli_label,property_key="name",property_value=cli_name)hyp_to_cli = Relationship(hyp_node, '產生', cli_node)self.graph.create(hyp_to_cli)tnb_to_cli = Relationship(tnb_node, '產生', cli_node)self.graph.create(tnb_to_cli)# 建立疾病與診斷方法之間的關系for diag_name in zd_method_list:diag_node = self.graph.find_one(label = diagnostic_label,property_key = "name",property_value = diag_name)if diag_name == "血糖" and diag_name == "血脂" and diag_name == "膽固醇":diag_to_dis = Relationship(diag_node, '輔助檢查', tnb_node)else:diag_to_dis = Relationship(diag_node, '輔助檢查', hyp_node)self.graph.create(diag_to_dis)# 建立疾病與藥物關系for drug_name in drug_list:drug_node = self.graph.find_one(label = dru_label,property_key = "name",property_value = drug_name)if drug_name == "胰島素" or drug_name == "胰高血糖素":drug_to_disease = Relationship(drug_node,'治療',tnb_node)else:drug_to_disease = Relationship(drug_node, '治療', hyp_node)self.graph.create(drug_to_disease)# 建立藥物與副作用之間的關系for drug_name in drug_list:drug_node = self.graph.find_one(label = dru_label,property_key = "name",property_value = drug_name)for sdef_name in sdef_list:sdef_node = self.graph.find_one(label = side_effect_label,property_key = "name",property_value = sdef_name)if drug_name == "利尿藥" and sdef_name == "尿酸升高":drug_to_sdef = Relationship(drug_node, '引發', sdef_node)self.graph.create(drug_to_sdef)elif drug_name == "鈣拮抗藥" and sdef_name == "血鉀降低":drug_to_sdef = Relationship(drug_node, '引發', sdef_node)self.graph.create(drug_to_sdef)elif drug_name == "胰島素" and (sdef_name == "惡心" or sdef_name == "嘔吐"):drug_to_sdef = Relationship(drug_node, '引發', sdef_node)self.graph.create(drug_to_sdef)elif drug_name == "胰高血糖素" and (sdef_name == "頭暈" or sdef_name == "眼花"):drug_to_sdef = Relationship(drug_node, '引發', sdef_node)self.graph.create(drug_to_sdef)c = createBHPData() c.clean_node() c.create_node() c.create_Rel()結果展示:
參考
總結
以上是生活随笔為你收集整理的【知识图谱实战】 Neo4j入门与示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【知识图谱】知识推理
- 下一篇: 【Keras】学习笔记(一)