Neo4j .NET客户端-获取从节点到根的路径 [英] Neo4j .NET Client - Getting a Path from a Node to its Root

查看:270
本文介绍了Neo4j .NET客户端-获取从节点到根的路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次尝试Neo4j. 我已经在控制台上进行了一些操作(Cypher查询),现在我正在尝试使用.NET客户端为.NET应用程序构建DAL.

I'm experimenting with Neo4j for the first time. I've played a bit with the console (Cypher queries) and now I'm trying to use the .NET client to build a DAL for a .NET application.

目前,我的数据模型非常简单:

For now, my data model is very simple:

  • 我有一个标签为文件夹"的节点.
  • 这些节点可能与其他文件夹节点具有"HAS_SUB_FOLDER"关系.

我已经成功完成了一些查询,例如

I've successfully done some queries such as

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

获取无父节点(即根目录中的文件夹"),该节点转换为:

to get the parent-less nodes (i.e. "folders in the root directory") which translates to:

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中.

现在,我要尝试对于给定的文件夹节点,找到其根目录的路径(以创建一些导航痕迹).我为此写的查询是:

Now I'm trying to, for a given folder node, find the path to its root (to create some navigational breadcrumbs). The query I wrote for that is:

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

这似乎可行.

但是,我无法使用.NET客户端实现该目标.我想获得一个给定节点的祖先文件夹的列表.我已经尝试过:

I can't, however, achieve that using the .NET client. I want to get a List with the ancestor folders for a given node. I have tried:

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:

But I get a: Accessed JArray values with invalid key value: "self". Array position index expected. with the following raw 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}"
  } ] ] ]
}

我可以看到正在检索所需的数据,但是反序列化时似乎出现了问题.我已经尝试对代码进行一些变体,但均未成功,并且我相信在尝试从检索到的路径中获取节点时,某处出现了新手错误.

I can see that the data I want is being retrieved but there seems to be a problem when deserializing it. I've tried some variations on my code, with no success and I believe I have a newbie mistake somewhere while trying to get the nodes from the retrieved path.

如果有人可以帮助我,我将不胜感激,因为我刚开始使用Neo4j(并且我仍然硬连线"以思考 MSB ),文档(仍然)仍然是稀疏,调试时遇到问题(每当我尝试查看Neo4j客户端库中任何变量的值时,我都会收到函数评估被禁用,因为先前的函数评估超时.您必须继续执行才能重新启用函数评估.").

I'd appreciate if someone could help me with this as I'm just starting using Neo4j (and I'm still "hardwired" to think RDBMS), the documentation is (still) a bit sparse and I'm having issues with debugging (whenever I try to peek into the values of any variable from the Neo4j client library, I get a "Function evaluation disabled because a previous function evaluation timed out. You must continue execution to reenable function evaluation.").

推荐答案

您已经关闭.只需将路径中的节点返回为IEnumerable<Folder>.

You were close. Just return the nodes in the path as 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.

This variable length match will actually return multiple paths. If you want longest path, right up to the root of the tree, sort the results by path length (descending) and limit to 1.

您也可以省略可变长度路径的minHops和maxHops,因为它们的默认值为1,并且无穷.您可以省略maxHops,因为它们的默认值为infinity,但我会将minHops设置为0;否则,您不能对根节点本身使用此查询.

You can also omit the minHops and maxHops of the variable length path since they default to 1 and infinity anyway. You can omit maxHops since it defaults to infinity but I would set minHops to 0; otherwise you can't use this query for the root node itself.

这就是我的写法:

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();

这篇关于Neo4j .NET客户端-获取从节点到根的路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆