在Neo4jClient .NET中检索所有相关节点,Cypher查询

时间:2013-03-27 12:55:54

标签: neo4j cypher neo4jclient

我有一个执行Cypher查询的方法,我希望返回所有节点及其与查询中指定节点(64)有关系的名称:

start n = node(64) match (n)--(x) return x.Name;

现在,当我尝试在我的代码中执行此操作时,它不想工作。这是我的方法:

public string GetAllFirstLevelRelatives(long NodeId)
{

    string QueryResult = null;

    try
    {
        var query = client_connection
            .Cypher
            .Start(NodeId, client_connection.RootNode)
            .Match(NodeId, "--(x)")
            .Return<Node<GraphNode>>("(x).name");

        QueryResult = query.Results.ToString();
    }
    catch (Exception e)
    {

    }
    return QueryResult;
}

我希望此查询返回名称。

有人可以帮我吗?

1 个答案:

答案 0 :(得分:7)

此查询:

start n = node(64) match n--x return x.Name;

应该用C#编写为:

var query = graphClient
    .Cypher
    .Start("n", node)           // START n=node(123)
    .Match("n--x")              // MATCH n--x
    .Return<string>("x.Name");  // RETURN x.Name

您提供的示例代码存在一些问题:

  1. 可能会有多个节点,但您的方法只返回一个string结果。调用Results.ToString()将返回类似"System.Collections.IEnumberable<string>"的内容,而不是实际结果。
  2. 您应避免将节点ID作为long传递。这样做可以鼓励您使用您不应该使用的原始数字。相反,请使用NodeReference。使用Neo4jClient运行的任何查询都会返回一个NodeReference对象。使用它来运行下一个查询。要开始您的第一个查询,我们提供IGraphClient.RootNode。您基本上不需要触摸节点ID。
  3. try {} catch {}部分为空的catch块中的任何.NET代码包装为总是一个大禁忌。请不要在任何代码中写这个。 :)
  4. x.Name可能是一个字符串,但之后您使用.Return<Node<GraphNode>>调用此字符串。这基本上是说“加载x.Name(一个字符串),但是将它作为Node<GraphNode>”返回给我。这没有多大意义。你需要匹配类型。
  5. 结合我上面写的查询和这些点,这就是你的方法应该是这样的:

    public IEnumerable<string> GetAllFirstLevelRelatives(NodeReference node)
    {
        var query = graphClient
            .Cypher
            .Start("n", node)           // START n=node(123)
            .Match("n--x")              // MATCH n--x
            .Return<string>("x.name");  // RETURN x.name
    
        return query.Results.ToList();
    }
    

    为了进一步改进,您应该利用我们的类型系统。您的查询中的“x”是什么?让我们想象一下这是一部电影。

    您应该创建一个描述电影节点包含内容的类:

    public class Movie
    {
        public string Name { get; set; }
    }
    

    该类应该是一个'POCO'(普通的旧类对象),这意味着它应该只有基本属性,而不是方法或逻辑。

    然后,在查询中使用此类型信息:

    public IEnumerable<Movie> GetAllRelatedMovies(NodeReference node)
    {
        var query = graphClient
            .Cypher
            .Start("n", node)
            .Match("n--movie")
            .Return<Movie>("movie");
    
        return query.Results.ToList();
    }
    

    现在你有一个电影列表,而不仅仅是一个字符串列表。您不太可能只想要电影的名称,这样您就可以访问所有属性。