如何在c#neo4jClient中创建一个唯一节点(如果已经存在则不重复)?

Posted

技术标签:

【中文标题】如何在c#neo4jClient中创建一个唯一节点(如果已经存在则不重复)?【英文标题】:How to create a unique node (not repeated if already exists) in c# neo4jClient? 【发布时间】:2013-12-10 17:55:23 【问题描述】:

我正在尝试执行以下操作(这在 neo4J 密码上很容易。

merge (ee:Person  id: "id1234" )

c#Neo4Jclient中如何保证下次创建不会再创建节点????

真的很需要这个

client.Cypher.Merge("(user:User Id: Id )")
.onCreate()
.set("user= newUser")
.withParams(new  ...  )
.executeWithoutResults();

似乎合并没有被选中。知道为什么吗?因为即使对象完全相同,它仍然会创建一个新节点。

谢谢, 回复

【问题讨论】:

我将对此进行调查。我认为在您的情况下理想的做法是将 Cypher 直接发送到 Neo4j。你现在用 Neo4jClient 用什么代码来创建? 您是否尝试过不使用 .onCreate() 进行合并? 【参考方案1】:

您的语法可能不正确。请使用以下语法以防止创建重复节点。

GraphClient client = GetNeo4jGraphClient();
client.Connect();

client.Cypher
    .Merge("(user:User Id: newUser.Id )")
    .OnCreate()
    .Set("user = newUser")
    .WithParams(
                new  
                    newUser =
                            new  
                                Id = 1, 
                                Name = "Michael", 
                                Title = "Developer Advocate", 
                                FavoriteDatabase = "Neo4j",
                                Occupation = "Software Developer"
                            
    )
    .ExecuteWithoutResults();

请注意,我已将上面的 Id 属性更改为 newUser.Id

这解决了重复问题,但如果您将此方法用作 GET/CREATE 用户的方法,则不会反映更新。例如,如果我将newUser.Name 属性更改为"Kenny",并且Id 属性保持不变,则原始ON CREATE 将优先并将节点恢复为原始状态。

要解决此问题,您需要做以下两件事之一。

    创建更新方法 将您的 MERGE 字符串作为 Cypher 发送,不带参数

选项 1 - 创建更新方法

创建一个看起来像这样的附加方法,将我的动态替换为您的 User 类:

GraphClient client = GetNeo4jGraphClient();
client.Connect();

client.Cypher.Match("(user:User Id: newUser.Id )")
    .Set("user = newUser")
    .WithParams(
                new
                
                    newUser =
                            new
                            
                                Id = 1,
                                Name = "Kenny",
                                Title = "Developer Advocate",
                                FavoriteDatabase = "Neo4j",
                                Occupation = "Software Developer"
                            
                )
    .ExecuteWithoutResults();

选项 2 - 将您的 MERGE 字符串作为 Cypher 发送,不带参数

我建议现在将 Cypher 直接发送到 Neo4j 服务器并绕过 Neo4jClient 中的 LINQ 扩展。

请查看这个修改后的基于 Neo4jClient 的 CypherQueryCreator.cs 文件:

https://github.com/kbastani/predictive-autocomplete/blob/master/predictive-autocomplete/PredictiveAutocomplete/CypherQueryCreator.cs

public static List<IGraphNode> MergeUser(User user)

     var sb = new StringBuilder();
     sb.AppendLine("MERGE user:User  Id: '0' ");
     sb.AppendLine("RETURN user");

     string commandQuery = sb.ToString();

     commandQuery = string.Format(commandQuery, user.UserId);

     GraphClient graphClient = GetNeo4jGraphClient();

     var cypher = new CypherFluentQueryCreator(graphClient, new CypherQueryCreator(commandQuery), new Uri(Configuration.GetDatabaseUri()));

     var resulttask = cypher.ExecuteGetCypherResults<GraphNode>();
     var graphNodeResults = resulttask.Result.ToList().Select(gn => (IGraphNode)gn).ToList();
     return graphNodeResults;

您可以在此处的同一个 GitHub 项目中找到类似的实现:

https://github.com/kbastani/predictive-autocomplete/blob/master/predictive-autocomplete/PredictiveAutocomplete/Processor.cs

转到“GetRankedNodesForQuery”方法。

注意:此实现没有利用 REST API 上推荐的参数使用。请查看相关文档以供考虑:

http://docs.neo4j.org/chunked/milestone/rest-api-cypher.html#rest-api-use-parameters

干杯,

肯尼

【讨论】:

以上是关于如何在c#neo4jClient中创建一个唯一节点(如果已经存在则不重复)?的主要内容,如果未能解决你的问题,请参考以下文章

使用 neo4jclient 确保唯一节点

如何在c ++中创建节点?

在 f# 中使用 Neo4jClient 创建带标签的节点

在firebase实时数据库中创建相同的节点

如何在 Neo4j v2 中使用 Neo4jClient 创建节点?

如何在 C# 中创建嵌入式 Neo4j 数据库