Part of my graph has the following schema:
Main part of the graph is the domain, that has some persons linked to it. Person has a unique constraint on the e
The first thing you need is to reliably resolve user ids so that they are consistent and globally unique. Now you said
user id is specific only for production database and is not globally used for other sources
From this, I can infer 2 things
So that means that source + user.id will be a GUID. (You can hash the main connection url or name each source externally) I will assume you aren't merging users across multiple sources, because duplicating and merging data over any network creates an update order paradox that should be avoided as much as possible (If two sources list different new contact numbers, who is correct?).
The querying logic should be agnostic to any version tracking you may be doing. If your versioning causes problems with the logic, add a meta label like :Versioned with indexed property isLatest and tack on a Where n.isLatest to filter out the old "garbage" data from your results.
So no that you don't need to worry about version, Queries 1 and 2 can be handled normally.
For finding people who are admins, I would recommend just adding a the label :Admin to the person and removing it when it no longer applies (as needed). This comes with being indexed by the label "Admin". You can also just use an "isAdmin" property (which is probably how you are already storing it in the db, so more consistent.) So the final query would just be MATCH (p:Person:Admin) or MATCH (p:Person{isAdmin:true}).
With the old version information filtered out, the query for who has a device would simply be MATCH (p:Person:Versioned{isCurrent:true})-[:HasDevice{isConnected:true}]->(d:Device:Versioned{isCurrent:true})
This bit really just boils down to "What is your schema?"
This bit is where it really gets tricky. Depending on how you version the data, You can easily end up blowing up your data size and killing your DB performance. You REALLY need to ask yourself "Why am I versioning this?", "How often will this update/be read?", "Who will use it and What will they do with it?". If at any point you answer "I don't know/care", you either shouldn't do this, or backup your data in a database that natively handles this for you like SQLAlchemy-Continuum. (Related answer)
If you must do this in Neo4j, than I would recommend using a delta chain. So if for example, you changed {a:1, b:2} to {a:1, b:null, c:3}, You would have (:Thing{a:1, b:null, c:3})-[_DELTA{timestamp:. That way, to get a past value you just chain-apply the properties of the delta chain into a map. So MATCH (a:Thing) OPTIONAL MATCH (a)-[d:_DELTA*]->(d) WHERE d.timestamp >= . This can get very tedious though and eat up your DB Space, so I would highly recommend using some existing db versioning thing at all costs if you can.