Objective
"Where did the money go?" is the first question in any money-laundering investigation, and in SQL it is a self-join for every hop. Model accounts and transfers as a property graph and it is a single pattern. This recipe traces funds downstream from a flagged account through layers of mule and shell accounts.
Step 1: Build a small transaction graph
Accounts are nodes; a transfer is a SENT edge carrying the amount. Note the classic layering
shape — sub-$10k hops through two shells to an offshore cashout.
MERGE (a:Account {id: "ACC-100", holder: "Flagged Co"})
MERGE (b:Account {id: "ACC-201", holder: "Shell A"})
MERGE (c:Account {id: "ACC-202", holder: "Shell B"})
MERGE (d:Account {id: "ACC-900", holder: "Offshore Cashout"})
MERGE (a)-[:SENT {amt: 9500}]->(b)
MERGE (b)-[:SENT {amt: 9300}]->(c)
MERGE (c)-[:SENT {amt: 9100}]->(d);
Step 2: Trace everything reachable from the flagged account
The variable-length pattern -[:SENT*1..4]-> follows the money up to four hops out in one query.
MATCH (a:Account {id: "ACC-100"})-[:SENT*1..4]->(x:Account)
RETURN DISTINCT x.id AS reached_account, x.holder AS holder;
Result — the full downstream chain, in one hop-query:
| reached_account | holder |
|---|---|
| ACC-201 | Shell A |
| ACC-202 | Shell B |
| ACC-900 | Offshore Cashout |
Why it matters
One pattern surfaces the whole mule chain that a SQL self-join would need four joins to reach. Feed the flagged account from a structuring alert, then walk the graph to see where the funds landed — and record the finding on a tamper-evident SAR ledger.
To find closed laundering rings (money returning to its origin) rather than downstream flow, see fraud-ring detection and money-laundering cycle detection.