我有一个"喜欢"在我设计的社交应用程序中。它看起来像这样:(在我发送它之前将其拆分以查看查询文本(使用executewihoutresults)
var client = new GraphClient(new Uri("http://localhost:7474/db/data"));
client.Connect();
var q = client.Cypher.Start(new {n = string.Format("node({0})", nodeId)})
.Match("(u:User)")
.Where((User u) => u.ProviderUserKey == id)
.Create("(n)-[:Liked_By]->(u)");
var res = q.Return(u => u.As<UserInfo>()).Results;
这在cypher中产生类似的东西:
START n=node(31)
MATCH (u:User)
WHERE (u.ProviderUserKey = 9)
CREATE (n)-[:Liked_By]->(u)
当我从Web控制台执行它时,它为我提供了在节点(n)和用户节点(u)之间创建关系的预期行为。但是,当我从.net执行它时,它会为用户创建一个新节点,并为我开始的任何节点创建一个新关系。
我相对较新,所以我希望这是非常明显的!如何编写此查询以便它只创建节点(可以是任何时间)与用户节点之间的关系?
提供的完整项目答案 0 :(得分:2)
您使用的是哪个版本的.NET客户端?
鉴于您上面的Cypher正在使用标签,看起来您正在使用相当新版本的Cypher / Neo4j,例如: Cypher 2和Neo4j 2.x。
如果您正在使用Cypher 2(并且.NET客户端支持它),请查看将查询更新为以下内容时会发生什么:
MATCH (u:User {ProviderUserKey: 9}), (n {id: 31})
CREATE (n)-[:Liked_By]->(u)
...并将其转换为.NET客户端使用的内容(此时我对.NET Neo4j客户端做的不多)。
说实话,如果您只想生成一次该关系,请考虑使用MERGE而不是CREATE(再次,如果您使用的是Cypher 2)。
对我来说,听起来.NET语句没有生成Cypher,其中图形识别用户节点,因此它被创建(希望听起来不太明显)。
让我们知道它是怎么回事。
答案 1 :(得分:1)
所以这是关于Merge关键字实际执行的经验教训。在之前的查询中,我在查询项目后合并了我认为是两个查询以获取项目的喜欢。 Merge语句正在创建一个具有相似关系的新用户节点。
我确实重写了我上面提到的查询,并且看起来像这样:
client.Cypher
.Start(new { n = string.Format("node({0})", nodeId) })
.Match("(u:User {ProviderUserKey : {id}})")
.WithParam("id", id)
.Create("(n)-[:Liked_By]->(u)").ExecuteWithoutResults();
仅具有创建关系所需的效果。感谢@BtySgtMajor让我走上正确的轨道(通过提及这种关系。
对于那些在家里玩的人来说,这是一个令人讨厌的问题:
var result = client.Cypher.Start(new { s = string.Format("node({0})", id) })
.Match("(u:User)<-[mb:Created_By]-(c:Comment)-[o:On_Item]->(s:Session)")
.Merge("(c)-[lb:Liked_By]->(lbu:User)") //bad line here
.Return((u, mb, c, s, o, lbu) =>
new { Comment = c.As<Comment>(), MadeByUser = u.Node<UserInfo>(), CommentNodeId = c.Id(), LikedByUsers = lbu.CollectAs<UserInfo>() })
.Results.Select(x =>
{
x.Comment.MadeBy = x.MadeByUser.Data;
x.Comment.MadeBy.NodeId = (int)x.MadeByUser.Reference.Id;
x.Comment.MadeBy.ProviderUserKey = x.MadeByUser.Reference.Id;
x.Comment.Id = (int)x.CommentNodeId;
x.Comment.LikedBy = x.LikedByUsers.Select(ui => new UserInfo { Username = ui.Data.Username, ProviderUserKey = ui.Reference.Id, NodeId = (int)ui.Reference.Id }).ToList();
return x.Comment;
});
我将Merge更改为OptionalMatch,它不再创建错误的用户节点!
但是,我觉得这不是一个干净的实现,并且有一种更好的方法来编写这个查询。我会在另一个问题上提出这个问题。