Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-13-2020 08:40 AM
This is my first time posting here, So Hopefully I am asking this question right.
I have a graph that has User Nodes that can be "friends" of each other. When a User is a friend, they can see each others data. I have an simplified example here with three User Nodes that are all friends with each other (The FAMILY_FRIEND relationship)
Now I also have PersonVersion Nodes. Users can make changes to each other's PersonVersion nodes, which will create a new Node with a PREVIOUS_VERSION relationship back to the old node. Users should get the version with changes that they made last The USER relationship otherwise they should use the friends with the latest version.
Here is some sample data:
CREATE
(`0` :User {name:'Mike'}) ,
(`1` :User {name:'Joe'}) ,
(`2` :PersonVersion {data:'v1', version_date:date('2020-1-2')}) ,
(`3` :PersonVersion {data:'v2', version_date:date('2020-1-3')}) ,
(`4` :PersonVersion {data:'v0', version_date:date('2020-1-1')}) ,
(`5` :PersonVersion {data:'OtherPersonV0', version_date:date('2020-1-1')}) ,
(`6` :PersonVersion {data:'differentpersonv0', version_date:date('2020-1-1')}) ,
(`7` :PersonVersion {data:'AnotherPersonV1', version_date:date('2020-1-2')}) ,
(`8` :PersonVersion {data:'AnotherPersonV0', version_date:date('2020-1-1')}) ,
(`9` :User {name:'Jack'}) ,
(`10` :PersonVersion {data:'FriendPersonv0', version_date:date('2020-1-2')}) ,
(`11` :PersonVersion {data:'SomeMergedPerson', version_date:date('2020-1-2')}) ,
(`12` :PersonVersion {data:'AFPv1', version_date:date('2020-1-2')}) ,
(`13` :PersonVersion {data:'AFPv2', version_date:date('2020-1-3')}) ,
(`14` :PersonVersion {data:'AFPv0', version_date:date('2020-1-1')}) ,
(`2`)-[:USER ]->(`0`),
(`3`)-[:USER ]->(`1`),
(`1`)-[:FAMILY_FRIEND ]->(`0`),
(`2`)-[:PREVIOUS_VERSION ]->(`4`),
(`3`)-[:PREVIOUS_VERSION ]->(`4`),
(`5`)-[:USER {deleted: true}]->(`0`),
(`6`)-[:USER ]->(`1`),
(`7`)-[:USER ]->(`1`),
(`8`)-[:USER ]->(`0`),
(`7`)-[:PREVIOUS_VERSION ]->(`8`),
(`0`)-[:FAMILY_FRIEND ]->(`9`),
(`10`)-[:USER ]->(`1`),
(`10`)-[:USER ]->(`9`),
(`7`)-[:PREVIOUS_VERSION ]->(`11`),
(`12`)-[:USER]->(`9`),
(`13`)-[:USER]->(`1`),
(`12`)-[:PREVIOUS_VERSION ]->(`14`),
(`13`)-[:PREVIOUS_VERSION ]->(`14`),
(`1`)-[:FAMILY_FRIEND ]->(`9`)
I can get as far as getting all the nodes with the deleted node removed from the result set:
MATCH path=(:User {name:'Mike'})-[:USER|FAMILY_FRIEND*]-(p:PersonVersion)
WHERE all(r in relationships(path) WHERE NOT exists(r.deleted))
RETURN p
Where I get lost is trying to figure out how to get only one PersonVersion from each of the PersonVersion subgraphs (i.e. v1, v2, v0 should only return v2 when queried by Mike or Jack, but should return v1 when queried by Joe)
I have built this in SQL and it was really hard. I have to store all the previous versions in an array for each row in the person_version table and then I use an Intersection test between the rows inside of a subquery inside a join. I am hoping that something like this is easier in Neo4j.
Perhaps there is something I can do in the model to make this easier?
I thought I might be getting close with this, but it doesn't do anything:
MATCH path=(:User {name:'Mike'})-[:USER|FAMILY_FRIEND*]-(p:PersonVersion)
WHERE any(n in nodes(path) WHERE NOT (p)<-[:PREVIOUS_VERSION]-(n))
RETURN p
However I think this is just looking at nodes in the current path. I need to compare with nodes from the rest of the results.
01-13-2020 04:02 PM
I'm a little lost with this part:
Joe has a :USER relationship with the v2 node, not v1. Did you mean that Joe and Jack should see v2 (Joe because he has a direct relationship to it, Jack because it's the newest version and he isn't directly connected to any of them) and that Mike should see v1 (since he's directly connected to that one)?
All the sessions of the conference are now available online