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

use*_*936 1 c# neo4j neo4jclient

我正在尝试执行以下操作(这在neo4J cypher上很容易.

merge (ee:Person { id: "id1234" })
Run Code Online (Sandbox Code Playgroud)

如何确保下一个创建不会在c#Neo4Jclient中创建另一个节点????

迫切需要这个

client.Cypher.Merge("(user:User {Id: {Id} })")
.onCreate()
.set("user= {newUser}")
.withParams(new { ... } )
.executeWithoutResults();
Run Code Online (Sandbox Code Playgroud)

似乎Merge没有被提升.知道为什么吗?因为即使对象完全相同,它仍然会创建一个新节点.

谢谢,R

Ken*_*ani 7

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

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();
Run Code Online (Sandbox Code Playgroud)

请注意,我已将Id酒店更改为{newUser}.Id上方.

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

要解决这个问题,你需要做两件事之一.

  1. 创建更新方法
  2. 将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();
Run Code Online (Sandbox Code Playgroud)

选项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;
}
Run Code Online (Sandbox Code Playgroud)

您可以在同一个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

干杯,

肯尼