As I stated on a different post, I am moving from SQL Server to Neo4j, so I'm fighting the learning curve. I've been doing fairly well at searching StackOverflow and google to answer my questions, but I have stumbled across a weird result of a query that doesn't make sense.
C# Code:
public void AddMarketInfo(MarketInfo mi)
{
Bid bid = mi.Bid;
Ask ask = mi.Ask;
var query = clientConnection.Cypher
.Merge("(newbid:Bid { ID: {bID} })")
.OnCreate()
.Set("newbid = {bid}")
.WithParams(new
{
bID = bid.ID,
bid
})
.Merge("(newask:Ask { ID: {aID} })")
.OnCreate()
.Set("newask = {ask}")
.WithParams(new
{
aID = ask.ID,
ask
})
.Merge("(newMarketInfo:MarketInfo { ID: {id}, ASK: {askID}, BID: {bidID} })")
.OnCreate()
.Set("newMarketInfo = {mi}")
.WithParams(new
{
id = mi.ID,
bidID = bid.ID,
askID = ask.ID,
mi
})
.CreateUnique("(newask)-[rA:Ask_Input_Data]->(newMarketInfo)")
.CreateUnique("(newbid)-[rB:Bid_Input_Data]->(newMarketInfo)");
query.ExecuteWithoutResults();
}
I'm currently debugging the program, so this statement is being executed on the same data multiple times. Yes, I am going into the database and deleting all nodes for now.
When creating the "Bid" node and the "Ask" node, it successfully merges with the existing node but the "MarketInfo" node is being duplicated.
Any thoughts why?
Edit 2: Modified Query
So I was doing some more reading in the neo4j documentation:
https://neo4j.com/docs/developer-manual/current/cypher/clauses/merge/#query-merge-on-create-on-match
The example they provided was:
Merge with ON CREATE and ON MATCH Merge a node and set properties if the node needs to be created.
Query.
MERGE (keanu:Person { name: 'Keanu Reeves' })
ON CREATE SET keanu.created = timestamp()
ON MATCH SET keanu.lastSeen = timestamp()
RETURN keanu.name, keanu.created, keanu.lastSeen
The query creates the 'keanu' node, and sets a timestamp on creation time. If 'keanu' had already existed, a different property would have been set.
So I modified my code to "do the same":
var query = graphClient.Cypher
.Merge("(newbid:Bid { ID: {bID} })")
.OnMatch()
.Set("newbid = {bid}")
.OnCreate()
.Set("newbid = {bid}")
.WithParams(new
{
bID = bid.ID,
bid
})
.Merge("(newask:Ask { ID: {aID} })")
.OnMatch()
.Set("newask = {ask}")
.OnCreate()
.Set("newask = {ask}")
.WithParams(new
{
aID = ask.ID,
ask
})
.Merge("(newMarketInfo:MarketInfo { ID: {id}, ASK: {askID}, BID: {bidID} })")
.OnCreate()
.Set("newMarketInfo = {mi}")
.WithParams(new
{
id = mi.ID,
bidID = bid.ID,
askID = ask.ID,
mi
})
.Merge("(newask)-[rA:Ask_Input_Data]->(newMarketInfo)")
.Merge("(newbid)-[rB:Bid_Input_Data]->(newMarketInfo)");
query.ExecuteWithoutResultsAsync();
and yet, the nodes MarketInfo nodes are still being duplicated. I think I'm heading down the right path now, but...there is still something I'm missing.
So here was the problem, and it annoys me...
You can't use "ID" as a parameter of object. You can use "Id" or "id" or "iD" but not "ID". Once I swapped over to using "Id", the node was never duplicated again.