0

我有一个执行 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;
}

我希望此查询返回名称。

有人可以帮我吗?

4

1 回答 1

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 作为longs 传递。这样做会鼓励您使用不应该使用的原始数字。相反,使用NodeReference. 使用 Neo4jClient 运行的任何查询都会NodeReference返回一个对象。使用它来运行您的下一个查询。为了开始您的第一个查询,我们提供IGraphClient.RootNode. 您基本上不需要触摸节点 ID。
  3. 将任何 .NET 代码包装在该部分为空的try {} catch {}块中始终是一个很大的禁忌。请不要在任何代码中写这个,永远。:)catch
  4. x.Name很可能是一个字符串,但后来你用.Return<Node<GraphNode>>. 这基本上是说“加载x.Name(一个字符串),但把它作为一个Node<GraphNode>“返回给我。这没有多大意义。您需要匹配类型。

结合我上面写的查询和这些要点,你的方法应该是这样的:

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

现在你有了一个电影列表,而不仅仅是一个字符串列表。您不太可能只想要电影的名称,因此您可以通过这种方式访问​​所有属性。

于 2013-03-28T01:03:16.860 回答