Question

I am trying to do the following (which is easy on neo4J cypher.

merge (ee:Person { id: "id1234" })

How to ensure that the next create does not create another node in c# Neo4Jclient????

Really need this urgently

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

It seems that the Merge does not get picked up. Any idea why? As it still creates a new node even if the object is exactly the same.

Thanks, R

Was it helpful?

Solution

Your syntax may be incorrect. Please use the syntax below to prevent creating duplicate nodes.

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();

Please note that I've changed the Id property to {newUser}.Id above.

This resolves the duplication problem but if you are using this as a method for GET/CREATE user then the updates will not be reflected. For instance if I changed the newUser.Name property to "Kenny", and the Id property stayed the same, the original ON CREATE would take precedence and revert the node back to its original state.

To work around this you'll need to do one of two things.

  1. Create an update method
  2. Send your MERGE string as Cypher without parameters

Option 1 - Create an update method

Create an additional method that looks like this, swap out my dynamic for your User class:

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();

Option 2 - Send your MERGE string as Cypher without parameters

I recommend sending Cypher directly to the Neo4j server and bypass the LINQ extension for now in Neo4jClient.

Please take a look at this modified Neo4jClient-based CypherQueryCreator.cs file:

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;
}

You can find a similar implementation in the same GitHub project here:

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

Go to the method "GetRankedNodesForQuery".

Note: This implementation does not take advantage of the recommended use of parameters over the REST API. Please review the documentation for this consideration:

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

Cheers,

Kenny

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top