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
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.
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:
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:
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