如何return多个节点使用最短路径?

How to return multiple nodes using shortest path?

我正在尝试用 C# 重新创建它:

    MATCH p=shortestPath((bacon:Person {name:"Kevin Bacon"})-[*]-(meg:Person {name:"Meg Ryan"}))
    RETURN p

但我发现所有示例仅使用最短路径 returns 是相同类型节点的列表。在这个例子中,我需要 return People 和 Movies 节点。 所以它开始是这样的:

    var shortestPath = graphClient.Cypher
            .OptionalMatch("p = shortestPath((bacon: Person )-[*] - (meg: Person ) )")
            .Where((Person bacon) => bacon.name == "Kevin Bacon ")
            .AndWhere((Person meg) => meg.name == "Meg Ryan")
            .Return(?)
            .Results;

我应该写什么而不是问号?

图表如下所示:

更新: 我在 neo4j 客户端的最短路径上找到的唯一信息是 Return All Nodes in Shortest Path as Object List 但我无法弄清楚。

好问题 - 很难解决,我想我已经做到了 - 虽然 - 它可能不是最高效的。

正如您所说 - 问题是多种类型 - 所以让我们开始设置,我正在使用扩展方法来使代码看起来更好一些:

public static class Extensions
{
    public static T ToObject<T>(this string value)
    {
        //deserialize into a 'Node' first
        var node = JsonConvert.DeserializeObject<Node>(value);

        //then take the 'data' from that and 'ToObject' to the correct thing.
        return ((JObject) node.data).ToObject<T>();
    }

    private class Node{
        public object data {get;set;}
    }
}

ToObject<T> 方法是我们用来将输出转换为对象的方法。

我有一套标准的 POCO 来表示数据(尽管属性的命名约定很糟糕):

public class Movie {
    public string title {get;set;}
    public string tagline {get;set;}
}

public class Person {
    public string name {get;set;}
    public int born {get;set;}
}

public class RolesRel {
    public IEnumerable<string> roles {get;set;}
}

好的 - 现在我们准备好了。我已将 Return 更改为如下所示:

var shortestPath = graphClient.Cypher
     .OptionalMatch("p = shortestPath((bacon: Person)-[*]-(meg: Person ) )")
     .Where((Person bacon) => bacon.name == "Kevin Bacon")
     .AndWhere((Person meg) => meg.name == "Meg Ryan")
     .Return(p => new {
        Nodes = Return.As<IEnumerable<string>>("nodes(p)"),
        Relationships = Return.As<IEnumerable<RolesRel>>("rels(p)")
     });

string 是我们用于反序列化多个节点类型的唯一通用选项。在这种情况下,由于关系都是相同的,我们在这方面都很好,只使用 POCO - 但如果不是这样,你最终也会为他们做我们为节点所做的事情。

接下来,我运行通过结果:


foreach (var result in shortestPath.Results)
{
    foreach (var node in result.Nodes)
    {
        if(node.Contains("name"))
            Console.WriteLine(node.ToObject<Person>().name);
        else if(node.Contains("title"))
            Console.WriteLine(node.ToObject<Movie>().title);
        else {
            Console.WriteLine("Unknown Node Type: " + node);
        }
    }
}

我在这里对 属性 名称进行天真的检查,我知道它属于一种节点类型,但不属于另一种节点类型 - 您可能想以另一种方式进行 - 但这是可行的。

显然 - 我只是输出到屏幕 - 但你可以访问对象本身。