6.15. The Graphity activity stream model

Find Activity Streams in a network without scaling penalty

This is an approach for scaling the retrieval of activity streams in a friend graph put forward by Rene Pickard as Graphity. In short, a linked list is created for every persons friends in the order that the last activities of these friends have occured. When new activities occur for a friend, all the ordered friend lists that this friend is part of are reordered, transferring computing load to the time of new event updates instead of activity stream reads.

[Tip]Tip

This approach of course makes excessive use of relationship types. This needs to be taken into consideration when designing a production system with this approach. See Section 17.5, “Capacity” for the maximum number of relationship types.

To find the activity stream for a person, just follow the linked list of the friend list, and retrieve the needed amount of activities form the respective activity list of the friends.

Query 

MATCH p=(me { name: 'Jane' })-[:jane_knows*]->(friend),(friend)-[:has]->(status)
RETURN me.name, friend.name, status.name, length(p)
ORDER BY length(p)

The returns the activity stream for Jane.

Result

me.namefriend.namestatus.namelength(p)
3 rows

"Jane"

"Bill"

"Bill_s1"

1

"Jane"

"Joe"

"Joe_s1"

2

"Jane"

"Bob"

"Bob_s1"

3

Try this query live create (_0 {`name`:"Joe"}) create (_1 {`name`:"Ted"}) create (_2 {`name`:"Bob_s1"}) create (_3 {`name`:"Bob"}) create (_4 {`name`:"Bill"}) create (_5 {`name`:"Bill_s1"}) create (_6 {`name`:"Bill_s2"}) create (_7 {`name`:"Joe_s2"}) create (_8 {`name`:"Jane"}) create (_9 {`name`:"Ted_s2"}) create (_10 {`name`:"Joe_s1"}) create (_11 {`name`:"Ted_s1"}) create (_0)-[:`jane_knows`]->(_3) create (_0)-[:`has`]->(_10) create (_1)-[:`bob_knows`]->(_4) create (_1)-[:`has`]->(_11) create (_3)-[:`has`]->(_2) create (_3)-[:`bob_knows`]->(_1) create (_4)-[:`jane_knows`]->(_0) create (_4)-[:`has`]->(_5) create (_5)-[:`next`]->(_6) create (_8)-[:`jane_knows`]->(_4) create (_10)-[:`next`]->(_7) create (_11)-[:`next`]->(_9) ; MATCH p=(me {name: 'Jane'})-[:jane_knows*]->(friend), (friend)-[:has]->(status) RETURN me.name, friend.name, status.name, length(p) ORDER BY length(p)

Figure 6.20. Graph