2013-12-18 56 views
1

我正在第一次嘗試使用Neo4j。 我玩過一些控制檯(Cypher查詢),現在我試圖使用.NET客戶端爲.NET應用程序構建DAL。Neo4j .NET客戶端 - 從節點到其根目錄獲取路徑

現在,我的數據模型很簡單:

  • 我有一個標籤,「文件夾」節點。
  • 這些節點可能與其他文件夾節點具有「HAS_SUB_FOLDER」關係。

我已經成功地做了一些疑問,如

MATCH (n:Folder) 
OPTIONAL MATCH n<-[r:HAS_SUB_FOLDER]-parent 
WITH n, count(parent) AS parents 
WHERE parents = 0 
RETURN n; 

得到它轉換到父無節點(即「在根目錄文件夾」):

var myQuery = client.Cypher.Match("(folder:Folder)") 
      .OptionalMatch("folder<-[r:HAS_SUB_FOLDER]-parent") 
      .With("folder, count(parent) AS parents") 
      .Where("parents=0") 
      .Return<Folder>("folder"); 
     var res = myQuery.Results.ToList(); 
// res is a List<Folder>, Folder is a Model in my MVC architecture containing attributes like an ID and a Name. 

在.NET中。

現在我想,對於給定的文件夾節點,找到路徑根(創建一些麪包屑導航)。我寫的查詢是:

MATCH (current:Folder {id: "...THE_ID..."}) 
MATCH p = ((current)<-[:HAS_SUB_FOLDER*1..5000]-()) 
RETURN p; 

這似乎工作。

但是,我不能實現使用.NET客戶端。我想獲得給定節點的祖先文件夾列表。我曾嘗試:

var getPathToRoot = client.Cypher.Match("(current:Folder)") 
      .Where((Folder current) => current.ID == id) 
      .Match("p = ((current) <- [:HAS_SUB_FOLDER*1.." + MAX_DEPTH + "]-())") 
      .Return<Folder>("NODES(p)"); 
var result = myQuery.Results.ToList(); 

但我得到一個:Accessed JArray values with invalid key value: "self". Array position index expected.具有以下原始JSON:

{ 
    "columns" : [ "NODES(p)" ], 
    "data" : [ [ [ { 
    "labels" : "http://localhost:7474/db/data/node/21721/labels", 
    "outgoing_relationships" : "http://localhost:7474/db/data/node/21721/relationships/out", 
    "data" : { 
     "Name" : "YYYYYYYY", 
     "ID" : "e5daef28-84c0-42a8-85bf-32516bfe47d0" 
    }, 
    "traverse" : "http://localhost:7474/db/data/node/21721/traverse/{returnType}", 
    "all_typed_relationships" : "http://localhost:7474/db/data/node/21721/relationships/all/{-list|&|types}", 
    "property" : "http://localhost:7474/db/data/node/21721/properties/{key}", 
    "self" : "http://localhost:7474/db/data/node/21721", 
    "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/21721/relationships/out/{-list|&|types}", 
    "properties" : "http://localhost:7474/db/data/node/21721/properties", 
    "incoming_relationships" : "http://localhost:7474/db/data/node/21721/relationships/in", 
    "extensions" : { 
    }, 
    "create_relationship" : "http://localhost:7474/db/data/node/21721/relationships", 
    "paged_traverse" : "http://localhost:7474/db/data/node/21721/paged/traverse/{returnType}{?pageSize,leaseTime}", 
    "all_relationships" : "http://localhost:7474/db/data/node/21721/relationships/all", 
    "incoming_typed_relationships" : "http://localhost:7474/db/data/node/21721/relationships/in/{-list|&|types}"}, 
    { 
    "labels" : "http://localhost:7474/db/data/node/21720/labels", 
    "outgoing_relationships" : "http://localhost:7474/db/data/node/21720/relationships/out", 
    "data" : { 
     "Name" : "XXXXXXXX", 
     "ID" : "31a4cde4-8584-418f-a122-a0f84bbfbf92" 
    }, 
    "traverse" : "http://localhost:7474/db/data/node/21720/traverse/{returnType}", 
    "all_typed_relationships" : "http://localhost:7474/db/data/node/21720/relationships/all/{-list|&|types}", 
    "property" : "http://localhost:7474/db/data/node/21720/properties/{key}", 
    "self" : "http://localhost:7474/db/data/node/21720", 
    "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/21720/relationships/out/{-list|&|types}", 
    "properties" : "http://localhost:7474/db/data/node/21720/properties", 
    "incoming_relationships" : "http://localhost:7474/db/data/node/21720/relationships/in", 
    "extensions" : { 
    }, 
    "create_relationship" : "http://localhost:7474/db/data/node/21720/relationships", 
    "paged_traverse" : "http://localhost:7474/db/data/node/21720/paged/traverse/{returnType}{?pageSize,leaseTime}", 
    "all_relationships" : "http://localhost:7474/db/data/node/21720/relationships/all", 
    "incoming_typed_relationships" : "http://localhost:7474/db/data/node/21720/relationships/in/{-list|&|types}" 
    } ] ] ] 
} 

我可以看到我想要的數據被檢索,但似乎有一個問題,反序列化時它。我嘗試了一些我的代碼的變體,但沒有成功,我相信在嘗試從檢索的路徑中獲取節點時,我在某處出現了一個新手錯誤。

我會很感激,如果有人可以幫助我,因爲我只是用Neo4j的開始(我還在「硬線」,以認爲RDBMS),該文件是(仍然)有點稀疏,我在調試時遇到問題(每當我試圖從Neo4j客戶端庫中查看任何變量的值時,我會得到一個「由於先前的函數評估超時而禁用了功能評估,必須繼續執行以重新啓用功能評估」)。 。

回答

3

你很近。只需返回路徑中的節點IEnumerable<Folder>

var getPathToRoot = client.Cypher.Match("(current:Folder)") 
    .Where((Folder current) => current.ID == id) 
    .Match("p = ((current) <- [:HAS_SUB_FOLDER*1.." + MAX_DEPTH + "]-())") 
    .Return(() => Return.As<IEnumerable<Folder>>("nodes(p)")); 

這個可變長度匹配實際上會返回多個路徑。如果你想要最長路徑,直到樹的根,按照路徑長度(降序)對結果進行排序並限制爲1.

你也可以省略可變長度路徑的minHops和maxHops,因爲它們默認無論如何,1和無限。您可以省略maxHops,因爲它默認爲無窮大,但我會將minHops設置爲0;否則,您不能將此查詢用於根節點本身。

這是我會怎麼寫呢:

var pathToRoot = client.Cypher 
    .Match("p = (current:Folder)<-[:HAS_SUB_FOLDER*0..]-()") 
    .Where((Folder current) => current.ID == id) 
    .Return(() => Return.As<IEnumerable<Folder>>("nodes(p)")) 
    .OrderByDescending("length(p)") 
    .Limit(1).Results.SingleOrDefault(); 
+0

嘿Bossie,在此先感謝!你的方法看起來是正確的,儘管我現在無法測試它,但明天我會這樣做。之後我會發布我的反饋。 – user1987392

+0

很好,它的工作原理。感謝您提供「.OrderByDescending(」length(p)「)」的提示:我注意到我的查詢可能會返回多個路徑,但我還沒有處理。一石二鳥殺死了兩隻鳥。 – user1987392