Implementation of newsfeed or timeline feature is a frequent requirement for social applications. The following exmaples are inspired by Newsfeed feature powered by Neo4j Graph Database. The query asked here is:
Starting at me, retrieve the time-ordered status feed of the status updates of me and and all friends that are connected via a CONFIRMED FRIEND relationship to me.
Query.
MATCH (me { name: 'Joe' })-[rels:FRIEND*0..1]-(myfriend)
WHERE ALL (r IN rels WHERE r.status = 'CONFIRMED')
WITH myfriend
MATCH (myfriend)-[:STATUS]-(latestupdate)-[:NEXT*0..1]-(statusupdates)
RETURN myfriend.name AS name, statusupdates.date AS date, statusupdates.text AS text
ORDER BY statusupdates.date DESC LIMIT 3
To understand the strategy, let’s divide the query into five steps:
FRIEND relationship (MATCH (me {name: 'Joe'})-[rels:FRIEND*0..1]-(myfriend)). Also, the WHERE predicate can be added to check whether the friend request is pending or confirmed.
MATCH myfriend-[:STATUS]-latestupdate).
NEXT relationships (MATCH (myfriend)-[:STATUS]-(latestupdate)-[:NEXT*0..1]-(statusupdates)) which will give you the latest and one additional statusupdate; adjust 0..1 to whatever suits your case.
ORDER BY statusupdates.date DESC).
LIMIT the number of updates you need in every query (LIMIT 3).
Here, the example shows how to add a new status update into the existing data for a user.
Query.
MATCH (me)
WHERE me.name='Bob'
OPTIONAL MATCH (me)-[r:STATUS]-(secondlatestupdate)
DELETE r
CREATE (me)-[:STATUS]->(latest_update { text:'Status',date:123 })
WITH latest_update, collect(secondlatestupdate) AS seconds
FOREACH (x IN seconds | CREATE latest_update-[:NEXT]->x)
RETURN latest_update.text AS new_status
Dividing the query into steps, this query resembles adding new item in middle of a doubly linked list:
STATUS relationship (OPTIONAL MATCH (me)-[r:STATUS]-(secondlatestupdate)).
STATUS relationship between user and secondlatestupdate (if it exists), as this would become the second latest update now
and only the latest update would be added through a STATUS relationship;
all earlier updates would be connected to their subsequent updates through a NEXT relationship. (DELETE r).
statusupdate node (with text and date as properties) and connect this with the user through a STATUS relationship
(CREATE me-[:STATUS]->(latest_update { text:'Status',date:123 })).
statusupdate or an empty collection to the next query part
(WITH latest_update, collect(secondlatestupdate) AS seconds).
NEXT relationship between the latest status update and the second latest status update (if it exists) (FOREACH(x in seconds | CREATE latest_update-[:NEXT]->x)).
Result
| new_status |
|---|
| 1 row |
| Nodes created: 1 |
| Relationships created: 2 |
| Properties set: 2 |
| Relationships deleted: 1 |
|
Copyright © 2014 Neo Technology