0
votes

Essentially, I have a set of transactions with senders and receivers:

Transaction 1 - Sender Joe - Receiver Bob
Transaction 2 - Sender Bob - Receiver Sam
Transaction 3 - Sender Bob - Receiver Nick

My goal is to take each unique sender and receiver and create a unique Person Node, with additional properties, like last_online and email, and eventually, the relationship chain (Person) -> sends -> (Transaction) -> to -> (Person). I have a small subset of these users already defined, and I want to combine the unknown and known users into the same set.

I've tried using merge and create_unique, and I end up creating duplicate nodes for every single Person-Transaction relationship, which I now understand why (As explained here). However, I still can't figure out how to accomplish what I'm trying to accomplish.

Edit: Here are the queries that I am running:

MATCH (t:Transaction) MERGE (p:Person{name:t.sender}) - [:sends] -> (t)
MATCH (t:Transaction) MERGE (t) - [:to] -> (p:Person{name:t.sender})

Each of these queries creates n wallets for each of the n transactions.

1
did you try unique constraints on the sender's properties?techie95
@ShaikRizwana yup. All the constraint does is block the merge clause from creating duplicates (by throwing an error) but beyond that, it's not actually creating the unique nodes and linking them across the query. The problem is that due to the nature of the merge function, it's perceiving every new "person where person.name = transaction.sender" as a unique node, so it tries to create a new node (and fails due to the constraint).thevises
Can you share with us your MERGE query ? I think you have done a mistake in itlogisima
@logisima Updated the post with the queries.thevises
@thevises did you try MERGE with ON MATCH SET and ON CREATE SET? that's how you avoid the duplicates and error too. If you apply unique constraint on name then no duplicate relations or nodes for. Can you also share the UI of the schema or the query's display?techie95

1 Answers

1
votes

You must carefully specify the pattern used with MERGE. If MERGE does not find an exact match on the entire pattern, it will create that entire pattern (even the parts of the pattern that already exist).

Something like the following should work (assuming that t also contains a transaction id and extra transaction data foo):

MERGE (s:Person {name: t.sender})
MERGE (r:Person {name: t.receiver})
MERGE (trans:Transaction {id: t.id})
SET trans.foo = t.foo
MERGE (s)-[:sends]->(trans)
MERGE (trans)-[:to]->(r);

To speed up processing, you should first create indexes on :Person(name) and :Transaction(id).