2013-12-18 27 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