使用Java客戶端將資料載入到Grakn知識圖中

Tybyq發表於2018-11-26

本教程說明了如何使用 Grakn的Java Client 將CSV,JSON或XML格式的資料集遷移到Grakn知識圖中

我們將在本文中討論的 phone_calls. 知識圖 稱為 此知識圖的模式在 此處 的前一篇文章中定義

如果您已經熟悉Grakn,並且您需要的只是一個遷移示例,您會發現 這個Github儲存庫 很有用。 如果,另一方面,你不熟悉的技術,一定要首先完成 定義模式 phone_calls 知識圖,使用Java資料遷移到Grakn閱讀進行了詳細的指導。

快速檢視phone_calls架構

在我們開始遷移之前,讓我們快速提醒一下 phone_calls 知識圖 的架構是如何形成的

使用Java客戶端將資料載入到Grakn知識圖中

將資料遷移到Grakn

我們將概述遷移的發生方式。

  1. 首先,我們需要與我們的Grakn鍵空間進行對話。 為此,我們將使用 Grakn Java客戶端

  2. 我們將遍歷每個資料檔案,提取每個資料項並將其解析為JSON物件。

  3. 我們將每個資料項(以JSON物件的形式)傳遞給其對應的模板。 模板返回的是用於將該項插入Grakn的Graql查詢。

  4. 我們將執行每個查詢以將資料載入到目標鍵空間 -  phone_calls

在繼續之前,請確保已安裝Java 1.8並在 計算機上 執行 Grakn伺服器

入門

建立一個新的Maven專案

該專案使用SDK 1.8並命名 phone_calls 我將使用IntelliJ作為IDE。

將Grakn設定為依賴關係

修改 pom.xml 以包含最新版本的Grakn(1.4.2)作為依賴項。

<?xml  version =“1.0”encoding =“UTF-8”?>
< project  xmlns = “”
         xmlns:xsi = “”
         xsi:schemaLocation = “ http://maven.apache.org/xsd/maven-4.0.0.xsd” >
    < modelVersion > 4.0.0 </ modelVersion >

    < groupId > ai.grakn.examples </ groupId >
    < artifactId > migrate-csv-to-grakn </ artifactId >
    < version > 1.0-SNAPSHOT </ version >

    < 儲存庫>
        < repository >
            < id >釋出</ id >
            < url > 
        </ repository >
    </ repositories >

    < properties >
        < grakn.version > 1.4.2 </ grakn.version >
        < maven.compiler.source > 1.7 </ maven.compiler.source >
        < maven.compiler.target > 1.7 </ maven.compiler.target >
    </ properties >

    < dependencies >
        < 依賴>
            < groupId > ai.grakn </ groupId >
            < artifactId > client-java </ artifactId >
            < version > $ {grakn.version} </ version >
        </ dependency >
    </ dependencies >
</ project >

配置日誌記錄

我們希望能夠配置Grakn登出的內容。 為此,請修改 pom.xml 以排除 slf4j 附帶 grakn logback 作為依賴 項新增


<?xml  version =“1.0”encoding =“UTF-8”?>
< project  xmlns = “”
         xmlns:xsi = “”
         xsi:schemaLocation = “ http://maven.apache.org/xsd/maven-4.0.0.xsd” >
    < modelVersion > 4.0.0 </ modelVersion >

    <! -  ...  - >

    < dependencies >
        < 依賴>
            < groupId > ai.grakn </ groupId >
            < artifactId > client-java </ artifactId >
            < version > $ {grakn.version} </ version >
            < exclusions >
                < 排除>
                    < groupId > org.slf4j </ groupId >
                    < artifactId > slf4j-simple </ artifactId >
                </ exclusion >
            </ exclusions >
        </ dependency >
        < 依賴>
            < groupId > ch.qos.logback </ groupId >
            < artifactId > logback-classic </ artifactId >
            < version > 1.2.3 </ version >
        </ dependency >
    </ dependencies >
</ project >

接下來,新增一個 logback.xml  使用以下內容 呼叫的新檔案 並將其放在下面 src/main/resources

< configuration  debug = “false” >
    < root  level = “INFO” />
</ configuration >

建立遷移類

src/main 建立一個名為的新檔案 Migration.java 這是我們要編寫所有程式碼的地方。

包括資料檔案

選擇以下資料格式之一併下載檔案。 下載四個檔案中的每個檔案後,將它們放在 src/main/resources/data 目錄下。 我們將使用它們將資料載入到我們的 phone_calls 知識圖中。

隨後的所有程式碼都將被寫入 Migration.java

指定每個資料檔案的詳細資訊

在此之前,我們需要一個結構來包含讀取資料檔案和構建Graql查詢所需的詳細資訊。 這些細節包括:

  • 資料檔案的路徑,和

  • 接收JSON物件並生成Graql插入查詢的模板函式。

為此,我們建立了一個名為的新子類 Input

匯入 mjson。傑森 ;

公共 類 遷移 {
    abstract  static  class  Input {
        字串 路徑 ;
        public  Input(String  path){
            這個。path  =  path ;
        }
        String  getDataPath(){ return  path ;}
        abstract  String  template(Json  資料);
    }
}

在本文的後面,我們將看到如何 Input 建立類 的例項 ,但在我們開始之前,讓我們將 mjson 依賴 項新增 檔案中 dependencies 標記中 pom.xml

< 依賴>
    < groupId > org.sharegov </ groupId >
    < artifactId > mjson </ artifactId >
    < version > 1.4.0 </ version >
</ dependency >

是時候初始化了 inputs

下面的程式碼呼叫 initialiseInputs() 返回集合的方法 inputs 然後,我們將使用 input 此集合中的 每個 元素將每個資料檔案載入到Grakn中。


//其他進口
匯入 java。util。ArrayList ;
匯入 java。util。收藏 ;

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}

    public  static  void  main(String [] args){
        集合< Input >  inputs  =  initialiseInputs();
    }

    static  Collection < Input >  initialiseInputs(){
        集合< Input >  inputs  =  new  ArrayList <>();
        // 接下來的是
        回報 輸入 ;
    }
}

公司的輸入例項


//進口

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}
    public  static  void  main(String [] args){...}

    static  Collection < Input >  initialiseInputs(){
        集合< Input >  inputs  =  new  ArrayList <>();

        輸入。add(new  Input(“data / companies”){
            @覆蓋
            public  String  template(Json  company){
                返回 “插入$ company isa company has name”  +  公司。at(“name”)+  “;” ;
            }
        });

        回報 輸入 ;
    }
}

input.getDataPath() 會回來的 data/companies

鑑於 company

{ name:“Telecom” }

input.template(company)  將返回

插入 $公司 ISA  公司 擁有 的名稱 “電信” ;

一個人的輸入例項

//進口

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}
    public  static  void  main(String [] args){...}

    static  Collection < Input >  initialiseInputs(){
        集合< Input >  inputs  =  new  ArrayList <>();

        輸入。add(new  Input(“data / companies”){...});

        輸入。add(new  Input(“data / people”){
            @覆蓋
            public  String  template(Json  person){
                //插入人
                String  graqlInsertQuery  =  “insert $ person isa person has phone-number”  +  person。at(“phone_number”);

                如果(! 人。有(“FIRST_NAME” )){
                    //人不是客戶
                    graqlInsertQuery  + =  “has is-customer false” ;
                } else {
                    //人是顧客
                    graqlInsertQuery  + =  “has is-customer true” ;
                    graqlInsertQuery  + =  “有名字”  +  人。at(“first_name”);
                    graqlInsertQuery  + =  “有姓氏”  +  人。at(“last_name”);
                    graqlInsertQuery  + =  “有城市”  +  人。在(“城市”);
                    graqlInsertQuery  + =  “有年齡”  +  人。在(“年齡”)。asInteger();
                }

                graqlInsertQuery  + =  “;” ;
                return  graqlInsertQuery ;
            }
        });

        回報 輸入 ;
    }
}

input.getDataPath() 會回來的 data/people

鑑於 person

{ phone_number:“+ 44 091 xxx” }

input.template(person)  將返回

插入 $人 擁有 電話- 數字 “+44 091 XXX” ;

並給予 person

{ 冷杉- 名稱:“成龍”,最後- 名:“喬”,城市:“即墨”,年齡:77,PHONE_NUMBER:“+00 091 XXX” }

input.template(person)  將返回

插入 $人 擁有 電話- 數字 “+44 091 XXX”  具有 第一- 名字 “成龍”  已經 過去- 名字 “喬”  有 城 “即墨”  具有 年齡 77 ;

合同的輸入例項

//進口

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}
    public  static  void  main(String [] args){...}

    static  Collection < Input >  initialiseInputs(){
        集合< Input >  inputs  =  new  ArrayList <>();

        輸入。add(new  Input(“data / companies”){...});

        輸入。add(new  Input(“data / people”){...});

        輸入。add(new  Input(“data / contracts”){
            @覆蓋
            public  String  template(Json  contract){
                //匹配公司
                String  graqlInsertQuery  =  “匹配$ company isa company has name”  +  contract。at(“company_name”)+  “;” ;
                //匹配人
                graqlInsertQuery  + =  “$ customer isa person has phone-number”  +  contract。at(“person_id”)+  “;” ;
                //插入合同
                graqlInsertQuery  + =  “insert(provider:$ company,customer:$ customer)isa contract;” ;
                return  graqlInsertQuery ;
            }
        });

        回報 輸入 ;
    }
}

input.getDataPath() 會回來的 data/contracts

鑑於 contract

{ company_name:“Telecom”,person_id:“ + 00 091 xxx” }

input.template(contract)  將返回

比賽 $公司 ISA  公司 擁有 的名稱 “電信” ; $客戶 ISA  人 擁有 電話- 數字 “+00 091 XXX” ; insert(provider:$ company,customer:$ customer)isa  contract ;

呼叫的輸入例項

//進口

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}
    public  static  void  main(String [] args){...}

    static  Collection < Input >  initialiseInputs(){
        集合< Input >  inputs  =  new  ArrayList <>();

        輸入。add(new  Input(“data / companies”){...});

        輸入。add(new  Input(“data / people”){...});

        輸入。add(new  Input(“data / contracts”){...});

        輸入。add(new  Input(“data / calls”){
            @覆蓋
            public  String  template(Json  call){
                //匹配來電者
                String  graqlInsertQuery  =  “match $ caller isa person has phone-number”  +  call。at(“caller_id”)+  “;” ;
                //匹配被叫者
                graqlInsertQuery  + =  “$ callee isa person has phone-number”  +  call。at(“callee_id”)+  “;” ;
                //插入電話
                graqlInsertQuery  + =  “insert $ call(caller:$ caller,callee:$ callee)isa call;”  +
                        “$ call已經開始”  +  來電。at(“started_at”)。asString()+  “;”  +
                        “$ call has duration”  +  call。在(“持續時間”)。asInteger()+  “;” ;
                return  graqlInsertQuery ;
            }
        });

        回報 輸入 ;
    }
}

input.getDataPath() 會回來的 data/calls

鑑於 call

{ caller_id:“44 091 XXX” ,callee_id:“00 091 XXX” ,started_at:2018 - 08 - 10 T07:57:51,持續時間:148 }

input.template(call)  將返回

比賽 $呼叫者 ISA  人 擁有 電話- 數字 “+44 091 XXX” ; $被叫 ISA  人 擁有 電話- 數字 “+00 091 XXX” ; insert  $ call(caller:$ caller,callee:$ callee)isa  call ; $電話 已經 開始- 在 2018 - 08 - 10 T07:57:51 ; $電話 具有 持續時間 148 ;

連線和遷移

現在我們已經為每個資料檔案定義了資料路徑和模板,我們可以繼續連線我們的 phone_calls 知識圖並將資料載入到其中。

//其他進口
進口 ai。grakn。GraknTxType ;
進口 ai。grakn。Keyspace ;
進口 ai。grakn。客戶。Grakn ;
進口 ai。grakn。util。SimpleURI ;
匯入 java。io。UnsupportedEncodingException ;

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}

    public  static  void  main(String [] args){
        集合< Input >  inputs  =  initialiseInputs();
        connectAndMigrate(輸入);
    }

    static  void  connectAndMigrate(Collection < Input >  inputs){
        SimpleURI  localGrakn  =  new  SimpleURI(“localhost”,48555);
        Keyspace  keyspace  =  Keyspace。of(“phone_calls”);
        Grakn  grakn  =  new  Grakn(localGrakn);
        Grakn。會話 會話 =  grakn。session(keyspace);

        輸入。forEach(輸入 - > {
            系統。出。的println(“[由載入”  +  輸入。getDataPath()+  “]成Grakn ...”);
            嘗試 {
                loadDataIntoGrakn(輸入,會話);
            } catch(UnsupportedEncodingException  e){
                e。printStackTrace();
            }
        });

        會議。close();
    }

    static  Collection < Input >  initialiseInputs(){...}

    static  void  loadDataIntoGrakn(輸入 輸入,Grakn。會話 會話)丟擲 UnsupportedEncodingException {...}
}

connectAndMigrate(Collection<Input> inputs) 是啟動資料遷移到 phone_calls 知識圖中 的唯一方法

此方法發生以下情況:

  1. grakn 建立 Grakn例項 ,連線到我們在本地執行的伺服器 localhost:48555

  2. session 建立 ,連線到鍵空間 phone_calls

  3. 對於 集合中的 每個 input 物件 inputs ,我們稱之為 loadDataIntoGrakn(input, session) 這將負責將 input 物件中 指定的資料載入 到我們的鍵空間中。

  4. 最後 session 關閉了。

將資料載入到phone_calls

現在我們已經 session 連線到 phone_calls 鍵空間,我們可以繼續將資料實際載入到我們的知識圖中。

//進口

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}

    public  static  void  main(String [] args){
        集合< Input >  inputs  =  initialiseInputs();
        connectAndMigrate(輸入);
    }

    static  Collection < Input >  initialiseInputs(){...}

    static  void  connectAndMigrate(Collection < Input >  inputs){...}

    static  void  loadDataIntoGrakn(輸入 輸入,Grakn。會話 會話)丟擲 UnsupportedEncodingException {
        ArrayList < Json >  items  =  parseDataToJson(輸入);
        物品。forEach(item  - > {
            Grakn。交易 tx  =  會話。交易(GraknTxType。WRITE);
            String  graqlInsertQuery  =  input。模板(專案);
            系統。出。println(“執行Graql查詢:”  +  graqlInsertQuery);
            tx。graql()。解析(graqlInsertQuery)。execute();
            tx。commit();
            tx。close();
        });
        系統。出。的println(“\ nInserted”  +  專案。大小()+  “由專案[”  +  輸入。getDataPath()+  “]。到Grakn \ n”個);
    }

    static  ArrayList < Json >  parseDataToJson(輸入 輸入)丟擲 UnsupportedEncodingException {...}
}

為了將每個檔案中的資料載入到Grakn中,我們需要:

  1. 檢索一個 ArrayList JSON物件,每個物件代表一個資料項。 為此,我們呼籲 parseDataToJson(input) ,和

  2. 對於每個JSON物件 items :a)建立事務 tx ,b)構造 graqlInsertQuery 使用相應的 template ,c)執行 query ,d) commit 事務和e) close 事務。

有關建立和提交事務的注意事項: 為避免記憶體不足,建議在單個事務中建立和提交每個查詢。 但是,為了更快地遷移大型資料集,每次查詢都會發生一次,其中是保證在單個事務上執行的最大查詢數。

現在我們已經完成了上述所有操作,我們已準備好讀取每個檔案並將每個資料項解析為JSON物件。 這些JSON物件將被傳遞給 template 每個 Input 物件 方法

我們要編寫實現 parseDataToJson(input)

DataFormat特定實現

parseDataToJson(input) 根據資料檔案的格式 ,實現會 有所不同。

但無論資料格式是什麼,我們都需要正確的設定來逐行讀取檔案。 為此,我們將使用 InputStreamReader

//其他進口
匯入 java。io。InputStreamReader ;
匯入 java。io。讀者 ;


公共 類 遷移 {
    抽象 靜態 類 輸入 {...}

    public  static  void  main(String [] args){...}

    static  void  connectAndMigrate(Collection < Input >  inputs){...}

    static  Collection < Input >  initialiseInputs(){...}

    static  void  loadDataIntoGrakn(輸入 輸入,Grakn。會話 會話)丟擲 UnsupportedEncodingException {...}

    public  static  Reader  getReader(String  relativePath)throws  UnsupportedEncodingException {
        返回 新 的InputStreamReader(遷移。類。getClassLoader()。的getResourceAsStream(relativePath),“UTF-8”);
    }
}

解析CSV

我們將使用 Univocity CSV Parser 來解析我們的 .csv 檔案。 讓我們為它新增依賴項。 我們需要在 dependencies 標籤中 新增以下內容 pom.xml

< 依賴>
    < groupId > com.univocity </ groupId >
    < artifactId > univocity-parsers </ artifactId >
    < version > 2.7.6 </ version >
</ dependency >

完成後,我們將編寫 parseDataToJson(input) 解析 .csv 檔案 的實現

//其他進口

進口 com。不公平。解析器。csv。CsvParser ;
進口 com。不公平。解析器。csv。CsvParserSettings ;

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}

    public  static  void  main(String [] args){...}

    static  void  connectAndMigrate(Collection < Input >  inputs){...}

    static  Collection < Input >  initialiseInputs(){...}

    static  void  loadDataIntoGrakn(輸入 輸入,Grakn。會話 會話)丟擲 UnsupportedEncodingException {...}

    static  ArrayList < Json >  parseDataToJson(輸入 輸入)丟擲 UnsupportedEncodingException {
        ArrayList < Json >  items  =  new  ArrayList <>();

        CsvParserSettings  settings  =  new  CsvParserSettings();
        設定。setLineSeparatorDetectionEnabled(true);
        CsvParser  解析器 =  新的 CsvParser(設定);
        解析器。beginParsing(getReader(輸入。getDataPath()+  “的.csv” ));

        String [] columns  =  parser。parseNext();
        String [] row ;
        而((行 =  分析器。parseNext())!=  空){
            Json  item  =  Json。object();
            對於(詮釋 我 =  0 ; 我 <  行。長度 ; 我++){
                專案。set(columns [ i ],row [ i ]);
            }
            物品。add(item);
        }
        返回 的專案 ;
    }

    public  static  Reader  getReader(String  relativePath)throws  UnsupportedEncodingException {
        返回 新 的InputStreamReader(遷移。類。getClassLoader()。的getResourceAsStream(relativePath),“UTF-8”);
    }
}

除了這個實現,我們還需要進行一次更改。

鑑於CSV檔案的性質,生成的JSON物件將把 .csv 檔案的 所有列 作為其鍵,即使該值不存在,它也將被視為一個 null

出於這個原因,我們需要在 person template input 例項 方法中 更改一行

if (! person.has("first_name")) {...}

if (person.at("first_name").isNull()) {...}

閱讀JSON

我們將使用 Gson的JsonReader 來讀取我們的 .json 檔案。 讓我們為它新增依賴項。 我們需要在 dependencies 標籤中 新增以下內容 pom.xml

< 依賴>
    < groupId > com.google.code.gson </ groupId >
    < artifactId > gson </ artifactId >
    < version > 2.7 </ version >
</ dependency >

完成後,我們將編寫 parseDataToJson(input) 用於讀取 .json 檔案 的實現

//其他進口
進口 com。谷歌。gson。流。JsonReader ;

公共 類 遷移 {
    抽象 靜態 類 輸入 {...}

    public  static  void  main(String [] args){...}

    static  void  connectAndMigrate(Collection < Input >  inputs){...}

    static  Collection < Input >  initialiseInputs(){...}

    static  void  loadDataIntoGrakn(輸入 輸入,Grakn。會話 會話)丟擲 UnsupportedEncodingException {...}

    static  ArrayList < Json >  parseDataToJson(輸入 輸入)丟擲 IOException {
        ArrayList < Json >  items  =  new  ArrayList <>();

        JsonReader  jsonReader  =  新 JsonReader(getReader(輸入。getDataPath()+  “上傳.json” ));

        jsonReader。beginArray();
        而(jsonReader。hasNext()){
            jsonReader。beginObject();
            Json  item  =  Json。object();
            而(jsonReader。hasNext()){
                String  key  =  jsonReader。nextName();
                開關(jsonReader。PEEK()){
                    案例 STRING:
                        專案。集(鍵,jsonReader。nextString());
                        打破 ;
                    案件 編號:
                        專案。集(鍵,jsonReader。nextInt());
                        打破 ;
                }
            }
            jsonReader。endObject();
            物品。add(item);
        }
        jsonReader。endArray();
        返回 的專案 ;
    }

    public  static  Reader  getReader(String  relativePath)throws  UnsupportedEncodingException {
        返回 新 的InputStreamReader(遷移。類。getClassLoader()。的getResourceAsStream(relativePath),“UTF-8”);
    }
}

解析XML

我們將使用Java的內建 StAX 來解析我們的 .xml 檔案。

要解析XML資料,我們需要知道目標標記的名稱。 這需要在 Input 類中 宣告 並在構造每個 input 物件 時指定

//進口

公共 類 XmlMigration {
    abstract  static  class  Input {
        字串 路徑 ;
        串 選擇 ;
        public  Input(String  path,String  selector){
            這個。path  =  path ;
            這個。selector  =  selector ;
        }
        String  getDataPath(){ return  path ;}
        String  getSelector(){ return  selector ;}
        abstract  String  template(Json  資料);
    }

    public  static  void  main(String [] args){...}

    static  void  connectAndMigrate(Collection < Input >  inputs){...}

    static  Collection < Input >  initialiseInputs(){
        集合< Input >  inputs  =  new  ArrayList <>();

        輸入。add(new  Input(“data / companies”,“company”){...});
        輸入。新增(新 輸入(“資料/人”,“人”){...});
        輸入。add(new  Input(“data / contracts”,“contract”){...});
        輸入。add(new  Input(“data / calls”,“call”){...});

        回報 輸入 ;
    }

    static  void  loadDataIntoGrakn(輸入 輸入,Grakn。會話 會話)丟擲 UnsupportedEncodingException,XMLStreamException {...}

    public  static  Reader  getReader(String  relativePath)throws  UnsupportedEncodingException {...}
}

現在用於 parseDataToJson(input) 解析 .xml 檔案 的實現

//其他進口
匯入 javax。xml。流。XMLInputFactory ;
匯入 javax。xml。流。XMLStreamConstants ;
匯入 javax。xml。流。XMLStreamException ;
匯入 javax。xml。流。XMLStreamReader ;

公共 類 XmlMigration {
    abstract  static  class  Input {
        字串 路徑 ;
        串 選擇 ;
        public  Input(String  path,String  selector){
            這個。path  =  path ;
            這個。selector  =  selector ;
        }
        String  getDataPath(){ return  path ;}
        String  getSelector(){ return  selector ;}
        abstract  String  template(Json  資料);
    }

    public  static  void  main(String [] args){...}

    static  void  connectAndMigrate(Collection < Input >  inputs){...}

    static  Collection < Input >  initialiseInputs(){
        集合< Input >  inputs  =  new  ArrayList <>();

        輸入。add(new  Input(“data / companies”,“company”){...});
        輸入。新增(新 輸入(“資料/人”,“人”){...});
        輸入。add(new  Input(“data / contracts”,“contract”){...});
        輸入。add(new  Input(“data / calls”,“call”){...});

        回報 輸入 ;
    }

    static  void  loadDataIntoGrakn(輸入 輸入,Grakn。會話 會話)丟擲 UnsupportedEncodingException,XMLStreamException {...}

    static  ArrayList < Json >  parseDataToJson(輸入 輸入)丟擲 UnsupportedEncodingException,XMLStreamException {
        ArrayList < Json >  items  =  new  ArrayList <>();

        XMLStreamReader  r  =  XMLInputFactory。newInstance()。createXMLStreamReader(getReader(輸入。getDataPath()+  “的.xml” ));
        字串 鍵 ;
        String  value  =  null ;
        Boolean  inSelector  =  false ;
        Json  item  =  null ;
        而([R 。hasNext()){
            int  event  =  r。next();

            開關(事件){
                case  XMLStreamConstants。START_ELEMENT:
                    如果(ř。號·getLocalName()。等於(輸入。getSelector())){
                        inSelector  =  true ;
                        item  =  Json。object();
                    }
                    打破 ;

                case  XMLStreamConstants。字元:
                    value  =  r。getText();
                    打破 ;

                case  XMLStreamConstants。END_ELEMENT:
                    key  =  r。getLocalName();
                    如果(inSelector  &&  ! 關鍵。平等(輸入。getSelector())){
                        專案。set(key,value);
                    }
                    如果(鍵。等於(輸入。getSelector())){
                        inSelector  =  false ;
                        物品。add(item);
                    }

                    打破 ;
            }
        }
        返回 的專案 ;
    }

    public  static  Reader  getReader(String  relativePath)throws  UnsupportedEncodingException {...}
}

把它放在一起

以下是我們 Migrate.java 將CSV資料載入到Grakn中的樣子,並在這裡找到 JSON XML 檔案的 樣子

包 ai。grakn。例子 ;

進口 ai。grakn。GraknTxType ;
進口 ai。grakn。Keyspace ;
進口 ai。grakn。客戶。Grakn ;
進口 ai。grakn。util。SimpleURI ;

/ **
 *用於CSV,TSV和固定寬度檔案的快速可靠的基於Java的解析器的集合
 * @see <a href="https://www.univocity.com/pages/univocity_parsers_documentation"> univocity </a>
 * /
進口 com。不公平。解析器。csv。CsvParser ;
進口 com。不公平。解析器。csv。CsvParserSettings ;

/ **
 *適用於Java的精簡JSON庫,
 * @see <a href="
 * /
匯入 mjson。傑森 ;

匯入 java。io。InputStreamReader ;
匯入 java。io。讀者 ;
匯入 java。io。UnsupportedEncodingException ;
匯入 java。util。ArrayList ;
匯入 java。util。收藏 ;

公共 課 CsvMigration {
    / **
     *表示將輸入檔案連結到自己的模板函式的Input物件,
     *用於將Json物件對映到Graql查詢字串
     * /
    abstract  static  class  Input {
        字串 路徑 ;

        public  Input(String  path){
            這個。path  =  path ;
        }

        String  getDataPath(){ return  path ;}

        abstract  String  template(Json  資料);
    }

    / **
     * 1.建立Grakn例項
     * 2.建立到目標鍵空間的會話
     * 3.初始化輸入列表,每個輸入包含解析資料所需的詳細資訊
     * 4.將csv資料載入到每個檔案的Grakn
     * 5.結束會議
     * /
    public  static  void  main(String [] args){
        集合< Input >  inputs  =  initialiseInputs();
        connectAndMigrate(輸入);
    }

    static  void  connectAndMigrate(Collection < Input >  inputs){
        SimpleURI  localGrakn  =  new  SimpleURI(“localhost”,48555);
        Grakn  grakn  =  new  Grakn(localGrakn);
        Keyspace  keyspace  =  Keyspace。of(“phone_calls”);
        Grakn。會話 會話 =  grakn。session(keyspace);

        輸入。forEach(輸入 - > {
            系統。出。的println(“[由載入”  +  輸入。getDataPath()+  “]成Grakn ...”);
            嘗試 {
                loadDataIntoGrakn(輸入,會話);
            } catch(UnsupportedEncodingException  e){
                e。printStackTrace();
            }
        });

        會議。close();
    }

    static  Collection < Input >  initialiseInputs(){
        集合< Input >  inputs  =  new  ArrayList <>();

        //定義用於構建公司Graql插入查詢的模板
        輸入。add(new  Input(“data / companies”){
            @覆蓋
            public  String  template(Json  company){
                返回 “插入$ company isa company has name”  +  公司。at(“name”)+  “;” ;
            }
        });
        //定義用於構造人Graql插入查詢的模板
        輸入。add(new  Input(“data / people”){
            @覆蓋
            public  String  template(Json  person){
                //插入人
                String  graqlInsertQuery  =  “insert $ person isa person has phone-number”  +  person。at(“phone_number”);

                如果(個人。在(“FIRST_NAME” )。參考isNull()){
                    //人不是客戶
                    graqlInsertQuery  + =  “has is-customer false” ;
                } else {
                    //人是顧客
                    graqlInsertQuery  + =  “has is-customer true” ;
                    graqlInsertQuery  + =  “有名字”  +  人。at(“first_name”);
                    graqlInsertQuery  + =  “有姓氏”  +  人。at(“last_name”);
                    graqlInsertQuery  + =  “有城市”  +  人。在(“城市”);
                    graqlInsertQuery  + =  “有年齡”  +  人。在(“年齡”)。asInteger();
                }

                graqlInsertQuery  + =  “;” ;
                return  graqlInsertQuery ;
            }
        });
        //定義用於構造合同的模板Graql插入查詢
        輸入。add(new  Input(“data / contracts”){
            @覆蓋
            public  String  template(Json  contract){
                //匹配公司
                String  graqlInsertQuery  =  “匹配$ company isa company has name”  +  contract。at(“company_name”)+  “;” ;
                //匹配人
                graqlInsertQuery  + =  “$ customer isa person has phone-number”  +  contract。at(“person_id”)+  “;” ;
                //插入合同
                graqlInsertQuery  + =  “insert(provider:$ company,customer:$ customer)isa contract;” ;
                return  graqlInsertQuery ;
            }
        });
        //定義用於構造呼叫Graql插入查詢的模板
        輸入。add(new  Input(“data / calls”){
            @覆蓋
            public  String  template(Json  call){
                //匹配來電者
                String  graqlInsertQuery  =  “match $ caller isa person has phone-number”  +  call。at(“caller_id”)+  “;” ;
                //匹配被叫者
                graqlInsertQuery  + =  “$ callee isa person has phone-number”  +  call。at(“callee_id”)+  “;” ;
                //插入電話
                graqlInsertQuery  + =  “insert $ call(caller:$ caller,callee:$ callee)isa call;”  +
                        “$ call已經開始”  +  來電。at(“started_at”)。asString()+  “;”  +
                        “$ call has duration”  +  call。在(“持續時間”)。asInteger()+  “;” ;
                return  graqlInsertQuery ;
            }
        });
        回報 輸入 ;
    }

    / **
     *將csv資料載入到我們的Grakn phone_calls鍵空間:
     * 1.將資料項作為json物件列表獲取
     * 2.對於每個json物件
     * 一個。建立Grakn事務
     * b。構造相應的Graql插入查詢
     * C。執行查詢
     * d。提交交易
     * e。關閉交易
     *
     * @param輸入包含解析資料所需的詳細資訊
     * @param會話將建立一個事務
     * @throws UnsupportedEncodingException
     * /
    static  void  loadDataIntoGrakn(輸入 輸入,Grakn。會話 會話)丟擲 UnsupportedEncodingException {
        ArrayList < Json >  items  =  parseDataToJson(輸入); // 1
        物品。forEach(item  - > {
            Grakn。交易 tx  =  會話。交易(GraknTxType。WRITE); // 2a
            String  graqlInsertQuery  =  input。模板(專案); // 2b
            系統。出。println(“執行Graql查詢:”  +  graqlInsertQuery);
            tx。graql()。解析(graqlInsertQuery)。execute(); // 2c
            tx。commit(); // 2d
            tx。close(); // 2e

        });
        系統。出。的println(“\ nInserted”  +  專案。大小()+  “由專案[”  +  輸入。getDataPath()+  “]。到Grakn \ n”個);
    }

    / **
     * 1.透過流讀取csv檔案
     * 2.將每行解析為json物件
     * 3.將json物件新增到項列表中
     *
     * @param輸入用於獲取資料檔案的路徑,減去格式
     * @return json物件列表
     * @throws UnsupportedEncodingException
     * /
    static  ArrayList < Json >  parseDataToJson(輸入 輸入)丟擲 UnsupportedEncodingException {
        ArrayList < Json >  items  =  new  ArrayList <>();

        CsvParserSettings  settings  =  new  CsvParserSettings();
        設定。setLineSeparatorDetectionEnabled(true);
        CsvParser  解析器 =  新的 CsvParser(設定);
        解析器。beginParsing(getReader(輸入。getDataPath()+  “的.csv” )); // 1

        String [] columns  =  parser。parseNext();
        String [] row ;
        而((行 =  分析器。parseNext())!=  空){
            Json  item  =  Json。object();
            對於(詮釋 我 =  0 ; 我 <  行。長度 ; 我++){
                專案。set(columns [ i ],row [ i ]); // 2
            }
            物品。add(item); // 3
        }
        返回 的專案 ;
    }

    public  static  Reader  getReader(String  relativePath)throws  UnsupportedEncodingException {
        返回 新 的InputStreamReader(CsvMigration。類。getClassLoader()。的getResourceAsStream(relativePath),“UTF-8”);
    }
}

載入時間

執行 main 方法,坐下來,放鬆並觀察日誌,同時資料開始湧入Grakn。

回顧一下

  • 我們從設定專案和定位資料檔案開始。

  • 接下來,我們繼續設定遷移機制,該機制獨立於資料格式。

  • 然後,我們瞭解瞭如何將具有不同資料格式的檔案解析為JSON物件。

  • 最後,我們執行了 使用給定 main 方法觸發 connectAndMigrate 方法的方法 inputs 這將資料載入到我們的Grakn知識圖中。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31557424/viewspace-2221683/,如需轉載,請註明出處,否則將追究法律責任。

相關文章