我有一个执行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;
}
我希望此查询返回名称。
有人可以帮我吗?
答案 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
您提供的示例代码存在一些问题:
string
结果。调用Results.ToString()
将返回类似"System.Collections.IEnumberable<string>"
的内容,而不是实际结果。long
传递。这样做可以鼓励您使用您不应该使用的原始数字。相反,请使用NodeReference
。使用Neo4jClient运行的任何查询都会返回一个NodeReference
对象。使用它来运行下一个查询。要开始您的第一个查询,我们提供IGraphClient.RootNode
。您基本上不需要触摸节点ID。try {} catch {}
部分为空的catch
块中的任何.NET代码包装为总是一个大禁忌。请不要在任何代码中写这个。 :)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();
}
现在你有一个电影列表,而不仅仅是一个字符串列表。您不太可能只想要电影的名称,这样您就可以访问所有属性。