News feed and relationships

123 views
Skip to first unread message

Fabio Tarantino

unread,
Apr 27, 2012, 11:18:38 AM4/27/12
to ne...@googlegroups.com
Hi,
i have a simple question on how to model a typical newsfeed for a social network...

My model consists of users and posts as nodes. Users are linked to other users with the "KNOWS" relationship. Users are linked to posts with the "WRITES" relationship.
I know that i can traverse relationships in a bidirectional way, so i could query all post nodes of a friend B of user A.
START n=node(A) MATCH n-[r:KNOWS]-B-[t:WRITES]->post RETURN B,post

Now i would introduce a blocking feature to not show posts of blocked friends. To do so i added a "block" property on the "KNOWS" relationship:
START n=node(A) MATCH n-[r:KNOWS]-B-[t:WRITES]->post WHERE t.block=0 RETURN B,post

That query works but it's not correct because if  A-KNOWS-B then A could block B but not viceversa.
So i need two KNOWS relationship between A and B ? Or there is a more efficient method?

thanks,
Fabio

Michael Hunger

unread,
Apr 27, 2012, 11:53:54 AM4/27/12
to ne...@googlegroups.com
Fabio,

you could have 2 properties (or one with a 3 state value 0 no block, 1 A blocks B, 2 B blocks A, 3 both block each other) that indicate direction of the block (or contain also semantic values about _what_ is blocked)

for your news-streams please look at the work around graphity by René Pickardt


Cheers

Michael

Fabio Tarantino

unread,
Apr 27, 2012, 4:31:11 PM4/27/12
to ne...@googlegroups.com
Hi Michael,
thank you for your quick response!
Though that solution seems don't work for me... How could i distinguish who blocks who, using properties in a simple way (i.e. with a generic cypher query)?

Suppose r is the relationship between A and B, and r.block is the property.
Look at these two queries:
1) match A-[r:knows]-B where r.block = ??
2) match B-[r:knows]-A where r.block = ??
the r.block property has obviously the same value, but in the first query i only know the ID of A and B is unknown, viceversa for the second query.
How i could express a semantic value in the correct order?

What do you think about using another relationship? for example:
match  A-[r:knows]-B, A-[!:blocks]->B where ...
is it faster than evaluating on properties?


thanks,
Fabio

Michael Hunger

unread,
Apr 27, 2012, 4:40:01 PM4/27/12
to ne...@googlegroups.com
fabio i meant numeric values of 0,1,2,3 for the blocked property

A second blocked relationship might be possible, depends on how many % of your users block things.

You can give the blocked-rel a try, if it doesn't work out it is pretty simple to convert it back to a property on the knows relationship.
It is faster to just check the relationship-type.

start ....
match a-[:KNOWS]->b
where not(a-[:BLOCKS]->b)

Michael

Cheers

Michael

Fabio Tarantino

unread,
Apr 27, 2012, 5:03:03 PM4/27/12
to ne...@googlegroups.com
Hi Micheal,
could you explain me how to convert the blocked-rel to a property on the knows relationship, please?
Note that i can't query a-[:KNOWS]->b but a-[:KNOWS]-b (i.e. without direction)

thanks again,
Fabio

Michael Hunger

unread,
Apr 27, 2012, 5:22:24 PM4/27/12
to ne...@googlegroups.com
Ok, if you don't know the relationship direction then it gets trickier,

we should add functions for determining the direction, start- and end-node to cypher anyway.

What you can do is to have two blocked properties which contain just the ID of the node that is blocked.

so you can compare 
(r.block1 = ID(a) || r.block2= ID(a) -> a is blocked
(r.block1 = ID(b) || r.block2= ID(b) -> b is blocked

Michael

Andres Taylor

unread,
Apr 28, 2012, 4:14:55 AM4/28/12
to ne...@googlegroups.com
On Fri, Apr 27, 2012 at 11:22 PM, Michael Hunger <michael...@neotechnology.com> wrote:
Ok, if you don't know the relationship direction then it gets trickier,

we should add functions for determining the direction, start- and end-node to cypher anyway.

Yes we should. What would that look like? Is having startNode(r) or something like that enough?

Andrés 

Michael Hunger

unread,
Apr 28, 2012, 4:57:49 AM4/28/12
to ne...@googlegroups.com
I think so,

startNode(r) endNode(r) otherNode(r,node) (or opposite), what would also be nice if startNode() endNode(), nodes() would take relationships and paths (after all a rel is a path of length 1).

and either direction(r, node) = 'IN', 'OUT' or predicates like isOutgoing(r, node)=true|false isIncoming(r,node) = true,false

Michael

Fabio Tarantino

unread,
May 4, 2012, 7:00:13 AM5/4/12
to ne...@googlegroups.com
Hi Micheal,
sorry for the late reply... i like your solution that use two properties on the KNOWS relationship, it's very simple and fast to use! Probably it's not so expressive as a relation, but it works perfectly.

Due to my curiosity, in the meanwhile i'm experimenting the other solution that use a custom relationship.
So i have introduced a generic "RESTRICTS" relationship (between two user nodes) to indicate that there is a particolar block.
Properties on this relationship specify the block type (for example RESTRICTS.hideUserFeed=1 blocks the newsfeed of the end node) .

However i have encountered a strange behaviuor when i try to use cypher for obtaining data... i've attached some Neoclipse screenshots for better understand the problem...
the "db.jpg" image shows a subgraph of my test database: the user node "angelinajolie" is connected to "johnnydeep", "serenaautieri" and "carolalt" nodes with the "KNOWS" relationship.
There is a "RESTRICTS" relationship between "angelinajolie" and "serenaautieri" in order to blocks "serenaautieri" newsfeed ( the value of hideUserFeed property is equal to 1).

So this should be the cypher query to obtaining the newsfeed of the user "angelinajolie" (id=18):
START n=node(18)
MATCH n-[r:KNOWS]-friend-[t:HAS_POST]->post, n-[z?:RESTRICTS]->friend
WHERE z.hideUserFeed?=0
RETURN friend, post

But as you can see on the attached images, that query returns "serenaautieri" posts...
I hope it's my fault :)

thanks,
Fabio
db.jpg
query1.jpg
query2.jpg
query3.jpg

Michael Hunger

unread,
May 4, 2012, 12:08:10 PM5/4/12
to ne...@googlegroups.com
a n.prop? expression always evaluates to true if the node or the property is not there.

What you want is to use n.prop!  see:

This is your graph and query in the neo4j console.


<db.jpg><query1.jpg><query2.jpg><query3.jpg>

Fabio Tarantino

unread,
May 4, 2012, 12:40:11 PM5/4/12
to ne...@googlegroups.com
mmmm

r.hideUserFeed!=0 always return 0 results... but this is correct from my point of view.
I used r.hideUserFeed?=0 because i want all posts of the friends except when (RESTRICS realationship exists AND r.hideUserFeed exists AND r.hideUserFeed=1)

sorry if my explanation is a bit unclear (and sorry for my english) :-)

thanks
Fabio

Michael Hunger

unread,
May 4, 2012, 12:51:06 PM5/4/12
to ne...@googlegroups.com
n.prop? returns automatically true when the n or prop _not_ exist otherwise the result of the expression

n.prop? returns automatically false when n not exists or prop not exists otherwise the result of the expression

Fabio Tarantino

unread,
May 4, 2012, 1:02:51 PM5/4/12
to ne...@googlegroups.com
Ok,
so it wasn't suffcient!

Now this expression works:
WHERE (z is null OR z.hideUserFeed!=0)

thanks very much, Micheal!

Fabio
Reply all
Reply to author
Forward
0 new messages