Prev |  | Next

## 7.11. Implementing newsfeeds in a graph

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.

    START me=node:node_auto_index(name='Joe')
    MATCH me-[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:

1. First Get the list of all my friends (along with me) through `FRIEND` relationship (`MATCH me-[rels:FRIEND*0..1]-myfriend`). Also, the `WHERE` predicate can be added to check whether the friend request is pending or confirmed.
2. Get the latest status update of my friends through Status relationship (`MATCH myfriend-[:STATUS]-latestupdate`).
3. Get subsequent status updates (along with the latest one) of my friends through `NEXT` relationships (`MATCH myfriend-[:STATUS]-latestupdate-[:NEXT*0..1]-statusupdates`).
4. Sort the status updates by posted date (`ORDER BY statusupdates.date DESC`).
5. `LIMIT` the number of updates you need in every query (`LIMIT x SKIP x*y`).

Result

name | date | text
--- | --- | ---
3 rows
0 ms
`"Joe"` | `6` | `"Joe status2"`
`"Bob"` | `4` | `"bobs status2"`
`"Joe"` | `3` | `"Joe status1"`

Here, the example shows how to add a new status update into the existing data for a user.

Query.

    START me=node:node_auto_index(name='Bob')
    MATCH me-[r?:STATUS]-secondlatestupdate
    DELETE r
    WITH me, secondlatestupdate
    CREATE me-[:STATUS]->(latest_update{text:'Status',date:123})
    WITH latest_update,secondlatestupdate
    CREATE latest_update-[:NEXT]-secondlatestupdate
    WHERE secondlatestupdate <> null
    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:

1. Get the latest update (if it exists) of the user through the `STATUS` relationship (`MATCH me-[r?:STATUS]-secondlatestupdate`).
2. Delete the `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`).
3. Now, create the new `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})`).
4. Now, create a `NEXT` relationship between the latest status update and the second latest status update (if it exists) (`CREATE latest_update-[:NEXT]-secondlatestupdate WHERE secondlatestupdate <> null`).

Result

new_status
1 row
Nodes created: 1
Relationships created: 2
Properties set: 2
Relationships deleted: 1
0 ms
`"Status"`

Copyright © 2013 Neo Technology

Prev | Up | Next
| Home |