天天看點

Neo4j 第四篇:使用.NET驅動通路Neo4j

本文使用的IDE是Visual Studio 2015 ,驅動程式是Neo4j官方的最新版本:Neo4j.Driver ,建立的類庫工程(Project)要求安裝 .NET Framework 4.5.2及以上版本,Neo4j官方提供的驅動程式使用起來非常簡單,非常依賴于Cypher語言,這使得該驅動程式能夠處理很多任務,但是,官方驅動程式僅支援标量類型的參數(Parameters),由于Neo4j的批量更新,例如,Cypher語言的foreach,unwind指令等用于批量操作,非常依賴于參數,這也成了官方驅動最大的缺點。

一,安裝Neo4j Driver

官方的.NET 驅動程式使用的是Blot協定,目前更新到1.72版本,依賴.NET Framework 4.5.2及以上版本

Neo4j 第四篇:使用.NET驅動通路Neo4j

1,依賴.NET Framework 4.6版本

建立Neo4jApp工程,配置工程的熟悉,設定目标架構(Target Framework)為.NET Framework 4.6

Neo4j 第四篇:使用.NET驅動通路Neo4j

2,安裝驅動程式

點選工具(Tools)菜單,通過NuGet Package Manager的控制台指令安裝Neo4j的.NET驅動程式,選用1.3.0版本的原因是項目較趕,暫時沒有時間去學習最新的版本。

Neo4j 第四篇:使用.NET驅動通路Neo4j
Neo4j 第四篇:使用.NET驅動通路Neo4j

在C#中引用驅動程式的命名空間:

using Neo4j.Driver.V1;      

二,驅動程式主要方法和對象

Neo4j驅動程式最核心的對象是:Driver對象,Session對象和Transaction對象。Driver對象用于連接配接資料庫,Session對象用于建立事務,事務對象用于執行Cypher查詢。事務隻能在Read或Write模式下執行,由于Driver對象不會解析Cypher查詢,它也不會檢測到事務執行的是寫,還是讀操作,是以,當一個寫模式事務執行的是讀操作,Neo4j資料庫會抛出錯誤,執行失敗。

Note that the driver does not parse Cypher and cannot determine whether a transaction is intended to carry out read or write operations. As a result of this, a 

write

 transaction tagged for 

read

 will be sent to a read server, but will fail on execution.

1,連接配接資料庫

Neo4j通過Driver對象來連接配接圖形資料庫,在建立Driver對象時,需要伺服器的連接配接位址(即bolt監聽位址,位址格式是"bolt://host:7687")和身份驗證資訊:user和password。

private readonly IDriver Driver;

public Neo4jProviders(string uri, string user, string password)
{
    Driver = GraphDatabase.Driver(uri, AuthTokens.Basic(user, password));
}      

驗證資訊通過auth token來提供,基礎驗證是AuthTokens.Basic(user,password)。

2,建立會話(Session)

在連接配接圖形資料庫之後,建立會話,會話是一系列事務(Transaction)的容器,用于建立事務執行的上下文,也就是說,事務必須在session的上下文中執行。Neo4j驅動程式提供三種格式的事務,最簡單的是自動送出事務模式,自動送出事務模式使用 Session對象的run()方法來實作。

示例代碼如下,在建立Session之後,以自動送出模式執行事務,在資料庫中建立一個節點,該節點具有标簽和屬性。

public void AddPerson(string name)
{
    using (var session = Driver.Session())
    {
        session.Run("CREATE (a:Person {name: $name})", new {name});
    }
}      

在Neo4j的驅動程式中,發送到Neo4j資料庫引擎的Cypher查詢語句包含兩部分:Query和Parameters,其中,Query是在資料庫中執行的Cypher語句,Parameters是傳遞引擎的參數,在Query中以$para_name格式來引用參數,在Parameters中,參數的名詞和$para_name中的para_name保持一緻。

自動送出事務隻包含一個Cypher語句,這意味着多個事務不能共享網絡資料包,進而表現出比其他形式的事務更低的網絡效率。自動送出事務旨在用于簡單的用例,例如學習Cypher或編寫一次性腳本時。 建議不要在生産環境中使用自動送出事務,或者在性能或彈性是主要問題時使用。

3,建立事務函數

事務函數是推薦的建立事務的方式,這種形式能夠以最小的查詢代碼實作多個多個查詢的輸入,能夠分離資料庫查詢和應用程式邏輯。

在Neo4j的事務中,讀寫操作都必須處于事務的上下文中。在Session對象中,當事務以自動送出模式執行(通過session.Run()函數調用)時,事務隻包含一個Cypher語句,但是,這種模式有一個缺點,當Cypher語句執行失敗時,事務不能重新執行(Replay)。Neo4j推薦使用事務函數模式,通過Session對象調用WriteTransaction()或 ReadTransaction()函數,并在事務函數包含事務單元,在事務執行失敗時,能夠在異常處理代碼中重新執行Cypher語句。

public void AddPerson(string name)
{
    using (var session = Driver.Session())
    {
        session.WriteTransaction(tx => tx.Run("CREATE (a:Person {name: $name})", new {name}));
    }
}      

三,參數化查詢

Cypher支援參數化查詢,在Cypher語句中,使用參數替代表達式,實體的ID,參數不能用于關系類型和标簽。在Neo4j資料庫中,參數能夠優化查詢,使得Cypher的執行計劃更容易被緩存,查詢更快速。在Cypher中,通過$param引用參數。

1,使用參數建立節點

在執行事務之後,Session傳回資料庫執行的結果,通過result.Summary檢視Cypher語句執行的結果。

public bool CreateSingleNode(string lable,string name)
{
    string query = string.Format("CREATE (n:{0} ", lable)+ @"{name: $name})";
    using (var session = Driver.Session(AccessMode.Write))
    {
        var result = session.WriteTransaction(tx=>tx.Run(query, new { name }));
        IResultSummary rs = result.Summary;
        return rs.Counters.NodesCreated == 1;
    }
}      

2,使用參數建立關系

通過new建立匿名類型,參數名是匿名類型的字段,字段名必須和Cypher語句中的參數($para)保持一緻。

public bool CreateRelationship(string RelationshipType,string SourceNodeName,string TargetNodeName)
{
    string query = string.Format(@"match (n),(m) where n.name=$source and m.name=$target create (n)-[:{0}]->(m);",RelationshipType);

    using (var session = Driver.Session())
    {
        var result = session.WriteTransaction(tx => tx.Run(query,new {source=SourceNodeName,target= TargetNodeName } ));
        IResultSummary rs = result.Summary;
        return rs.Counters.RelationshipsCreated == 1;
    }
}      

四,查詢資料庫

向Neo4j資料庫發送請求,傳回的是資料結構是一個表格,Title是return子句的投影的字段。

Neo4j 第四篇:使用.NET驅動通路Neo4j

如示例圖所示,查詢傳回的結構是表格(行-列)式的,列值主要分為兩種,要麼是節點的屬性清單,以JSON結構顯示,要麼是标量值。

驅動程式的Session傳回查詢的結果,Keys字段是Cypher語句中return子句投影的字段清單;Values字段傳回是查詢結果。

public void MatchNodes(string lable, string name)
{
    string query = string.Format(@"MATCH (n:{0} ", lable)+ @"{name: $name})-[r]->(m) RETURN n,id(n);";
    using (var session = Driver.Session(AccessMode.Read))
    {
        var result = session.ReadTransaction(rx => rx.Run(query, new { name }));
        //return 子句投影的字段清單
        IReadOnlyList<string> keys = result.Keys;
        //查詢傳回的資料行
        var rows = result.ToList();
        foreach(var row in rows)
        {
            //每個資料行都包含多個資料列
            var columns = row.Values;
            foreach (var column in columns)
            {
                //每個資料列,可能是一個節點,也可能是一個标量值
                if(column.Key=="n")
                {
                    var node = column.Value as INode;

                    long NodeID = node.Id;
                    string NodeLables = string.Join(",", node.Labels.ToArray());
                    foreach (var property in node.Properties)
                    {
                        string Property=string.Format("Property[Key:{0},Value:{1}", property.Key, property.Value);
                    }
                }
                        
                if(column.Key=="id(n)")
                {
                    long NodeID=long.Parse(column.Value.ToString());
                }
            }
        }       
    }
}      

五,Cypher和.NET的類型映射

 驅動程式把程式設計語言翻譯成Cypher的類型系統,為了處理資料,需要了解程式設計語言的類型和Cypher的類型系統的映射。圖的特有類型是:Node、Relationship和Path,基礎類型:Boolean、Integer、Float、String、List、Map,對.NET的類型映射是:

Neo4j 第四篇:使用.NET驅動通路Neo4j

語句執行的結果是由記錄流(record stream)構成,結果通常由接收應用程式在到達時處理。一個記錄是一個由Key/Value對構成的有序字典(Map),記錄可以通過位置索引(0-based整數)和鍵(key,字元串)來通路。

Neo4j 第四篇:使用.NET驅動通路Neo4j

例如,通過位置索引來選擇記錄:

public List<string> GetPeople()
{
    using (var session = Driver.Session())
    {
        //return session.ReadTransaction(tx => tx.Run("MATCH (a:Person) RETURN a.name AS name").ToList());
        return session.ReadTransaction(tx =>
        {
            var result = tx.Run("MATCH (a:Person) RETURN a.name ORDER BY a.name");
            return result.Select(record => record[0].As<string>()).ToList();
        });
    }
}      

參考文檔:

neo4j Driver Manual

3.2.4. Parameters

Nuget Neo4j Driver 1.3.0

Chapter 4. Drivers

Working with Cypher values

作者

:悅光陰

出處

:http://www.cnblogs.com/ljhdo/

本文版權歸作者和部落格園所有,歡迎轉載,但未經作者同意,必須保留此段聲明,且在文章頁面醒目位置顯示原文連接配接,否則保留追究法律責任的權利。