Hi all, and thanks for helping. Thanks for the tip, I didn't convey the intentions clear enough.
I have a car node that has a serial number as a property. There will only ever be car nodes that have unique serial numbers. I have a state node with a name property. I will only have one state node with a property named Florida (but 50 other state nodes with different names of course).
Now that i've painted that picture. My car goes on trips between states. Each time a car leaves a state I get an event that tells me it left. Each time a car arrives I get an event that tells me it arrived at X state. Sometimes I won't get an event that tells me that I arrived at state X, but will sometimes get an event that tells me I'm leaving X.
Enter TRIP node. It has an edge LOCATION pointing to the state, that edge has two properties - arrive date property and a depart date property.
Scenario 1:
Pretend we have this already in the graph at T0.
trip 1
(c:Car {serialNumber:123})-[ta:TAKES]->(t:TRIP)-[l:LOCATION {arrived: 2019/1/1, departed: 2020/02/02})]-> (s:State {name: "California"})
trip2
(c:Car {serialNumber:123})-[ta:TAKES]->(t:TRIP)-[l:LOCATION {arrived: 2021/4/5})]-> (s:State {name: "California"})
Notice I have no departed date on trip 2, because we haven't left yet. At T1, we get an event that says we departed cali. So this one is easy, simply query where there is no end date on the location edge, update it with the date. It's easy because the location is already in the graph. But it's not because we need to do more in a single query, as you will see below. So let's keep going.
Scenario 2
Pretend we have this in the graph at T0
trip 1.
(c:Car {serialNumber:123})-[ta:TAKES]->(t:TRIP)-[l:LOCATION {arrived: 2019/1/1, departed: 2020/02/02})]-> (s:State {name: "California"})
For some reason, we never received an event for the arrival on the trip2 (from scenario 1 above) for date 2021/4/5. But we get a departure event. So, now we need to create the takes edge, the Trip node and the Location edge and connect them to the car and the state node and set the locations property departureDate value.
MATCH for a location where there is no departure date, and if there isn't a location, create one? How do we do that in one single query?
Scenario 3
Now, let's throw a wrench in the spokes. Pretend we have the same existing data as scenario 2. However, at the same exact time (milliseconds apart) we receive 2 events - an arrival in California AND a departure in California. And those events are processed on two different threads asynchronously.
I need to ensure that only one set of the takes edge, the Trip node and the Location edge are created and attached to the car and state. One thread will clearly win and create the takes edge, the Trip node and the Location edge. The other thread, running the same source code, will need to find the one(location edge) that was just created milliseconds ago, and update either arrival or departure date, respectively, depending on which event is being processed second.
I was toying around with apoc.do.when to run some conditional code if there is no location with a null departure date. This is why I can't use merge, because merge doesn't seem to like merging on something with a null/missing property (t:TRIP)-[l:LOCATION { departed: NULL })].
Using apoc.do.when it may let me MATCH for l:LOCATION where departed is null, if there is no location, then create one, otherwise update the existing location node's departed date.
Make sense?