I have quite a bit of data I query via JDBC (and CSV/XLS) and I will typically solve this with a few methods:
1: Store a node that timestamps the LAST time I ran an import procedure:
MATCH (dl:Dataloader {name:'mydatasource'})
WITH dl.lastrun as lastimporttimestamp
set dl.lastrun=timestamp()
....
Then in my JDBC query
SELECT property1,property2,property3 WHERE createdate > ''+lastimporttimestamp+''
So this gives you ONLY the newer values. (I'll perform a similar check using WHERE modifieddate >)
Obviously this only works if your datasource has create and modified datestamps stored that you can use to narrow down the dataset.
Then I will have a more complex "modify" procedure that performs several OPTIONAL MATCH operations to find existing nodes, relationships, and properties, and then modifies/adds/removes nodes/relationships/properties using FOREACH:
FOREACH (ignoreMe in CASE WHEN coalesce(x.property,'isnull') <> coalesce(row.property,'isnull') THEN [1] ELSE [] END | SET x.property=row.property)
This does add a LOT of complexity to the code, so I only do this if the datasets are larger, or I want to perform very efficient updates frequently.
I use this method to update my graph with Ticket information from our CRM system to perform automation on tickets because I want to freshen my neo4j DB every 5 minutes, but it would be impractical to re-import thousands of :Tickets and charges every 5 minutes.
But if I import data nightly from a static CSV file, I may do something a bit more blunt. Prior to the import I'll mark all the nodes as unverified:
MATCH (n:Mynodelabel) set n.unverified=true
Then as I do a MATCH or MERGE as I ingest the csv with that node within the code, I will perform:
REMOVE n.unverified
This indicates, ok this node is good, we found it again in the CSV.
Finally at the end of the import process I will just get rid of unverified nodes (as they must no longer exist):
MATCH (n:Mynodelabel {unverified:true}) DETACH DELETE n