pewpewlasers
pewpewlasers

Reputation: 3225

Neo4j user status privacy setting model

I am following this article to setup a system where users can follow each other and also become friends : http://neo4j.com/docs/stable/cypher-cookbook-newsfeed.html

A user (A) can friend another user (B) and hence A is automatically following B. User A can also follow B without adding B as a friend. Hence there should be a distinction made to the feed results. If A and B are not confirmed friends, A should get status updates from B that are marked public only. If A is a confirmed friend of B, A should get all status updates from B. A, even if is B's friend, can also unfollow his/her feed. (typical facebook model?). So basically I need to check who A follows and grab their updates. However, while doing this I also need to check if A has access to these status updates.

Is there an easy cypher to implement this? Or do you have a better model in mind? Assuming all updates are public following query should work. How would you add privacy setting dimension to it if there are friends only posts too?

MATCH (me { name: 'Joe' })-[rels:FOLLOWS*0..1]-(anotherUser)
WITH anotherUser
MATCH (anotherUser)-[:STATUS]-(latestupdate)-[:NEXT*0..1]-(statusupdates)
RETURN anotherUser.name AS name, statusupdates.date AS date, statusupdates.text AS text
ORDER BY statusupdates.date DESC LIMIT 3

Upvotes: 1

Views: 116

Answers (1)

FrobberOfBits
FrobberOfBits

Reputation: 18022

Yes, you can implement all of these requirements, it seems to me to boil down to a few extra carefully chosen WHERE clauses.

Here's your base query, with modifications:

MATCH (me { name: 'Joe' })-[rels:FOLLOWS*0..1]-(anotherUser)
WITH anotherUser
MATCH (anotherUser)-[:STATUS]-(latestupdate)-[:NEXT*0..1]-(statusupdates)
WHERE statusupdates.visibility='PUBLIC'
RETURN anotherUser.name AS name, statusupdates.date AS date, statusupdates.text AS text
ORDER BY statusupdates.date DESC LIMIT 3

Here, I've just added a WHERE to check for visibility=PUBLIC (which I made up, because the sample app doesn't specify those things; that would have to be part of your model one way or another).

You might consider doing that query along with a UNION to another query, which would be intended to fetch only those status updates from friends. (If it's a friend, then it doesn't matter what the visibility is)

MATCH (me { name: 'Joe' })-[:FRIEND]-(friend)-[:STATUS|NEXT*1..]->(statusupdates)
RETURN statusupdates
ORDER BY statusupdates.date DESC LIMIT 3;

Instead of using UNION you could also combine the two queries with an OPTIONAL MATCH clause on the second pattern. But either way, basically, your query needs to get the list of all status updates that are either people you follow whose posts are public, friends posts, or both. So conceptually it's easy to break that into those two separate cases, and then UNION the two result sets together.

Upvotes: 2

Related Questions