Neo4J创建从.net客户端到web客户端有不同的结果
本文关键字:客户端 结果 创建 net Neo4J web | 更新日期: 2023-09-27 18:02:32
我在我的人工社交应用程序中有一个"喜欢"的方法。它看起来像这样:(在我发送查询文本之前将其拆分以查看查询文本)(使用executewithoutresults)
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;
生成如下代码:
START n=node(31)
MATCH (u:User)
WHERE (u.ProviderUserKey = 9)
CREATE (n)-[:Liked_By]->(u)
当我从web控制台执行它时,它给了我在节点(n)和用户节点(u)之间创建关系的预期行为。然而,当我从。net执行它时,它为用户创建了一个新节点,并为我开始的任何节点创建了一个新关系。
我是新手,所以我希望这是非常明显的!我如何编写这个查询,以便它只创建节点(可以是任何时间)与用户节点之间的关系?
完整的项目可在https://github.com/fauxtrot/angular-ts-proto
您使用的是什么版本的。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,所以它正在被创建(希望这听起来不太明显)。
这是关于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;
});
我将合并更改为OptionalMatch,它不再创建错误的用户节点!
然而,我觉得这不是一个干净的实现,有一个更好的方式来编写这个查询。我会在另一个问题中提出这个问题。