1

For a few days now, I've been designing a social network database structure and I've been optimizing over and over again the data structures.

What I am trying to achieve in Neo4j:

I am trying to create a relationship between two nodes which has a property called "history" and one called "currentStatus". The problem is that both are (should be) arrays. Something like:

MATCH (u:User {username: 'john.snow@gmail.com'}), (uu:User {username: 'sansa.stark@gmail.com'}) 
MERGE u-[rel:FRIENDSHIP]->uu
ON CREATE SET rel.previousFriendshipUpdates = [], rel.currentFriendshipStatus = [sentTime: timestamp(), status: '0']
ON MATCH SET rel.previousFriendshipUpdates = [rel.previousFriendshipUpdates + rel.currentFriendshipStatus], rel.currentFriendshipStatus = [sentTime: timestamp(), status: '1']

I want to keep a history of whatever actions regarding they're friendship take place (sender sent friend request at x time, receiver rejected friend request at x time, sender sent friend request (again) at x time, receiver accepted at x time, receiver unfriended sender at x time, etc).

Thank you in advance.

Andrei Durduc
  • 280
  • 3
  • 8
  • Could you clarify what your question is? – jjaderberg Sep 11 '15 at 14:23
  • Sure, sorry if I wasn't explicit enough. My question is how can I create a relationship which has a property containing a multidimensional array (history, in which I will save earlier versions of this property) and another property - a single level array, containing the current friendship status and timestamp. – Andrei Durduc Sep 11 '15 at 14:35
  • Arrays are one-dimensional in Neo4j, they are just sequences of values. The solution is to spread your model over more nodes (see my answer for an example). – jjaderberg Sep 11 '15 at 14:39
  • My comment was unclear, what I meant to say was that arrays are sequences of values and the only index is that sequence-you can't have key/value pairs or named values in an array. You can, however, have arrays in arrays, so you can of course have multi-dimensional arrays that way. Is that what you want to do? – jjaderberg Sep 11 '15 at 15:00

1 Answers1

4

To add values to array (collection) property arr on relationship r you can do

SET r.arr = r.arr + 'newvalue'

or

SET r.arr = r.arr + ['onevalue', 'nothervalue']

(see How to push values to property array Cypher-Neo4j)

But arrays cannot contain values like sentTime: timestamp(). That looks like a property and an array can't have properties.

Nodes can have properties, however, and both the structure of your example query and the description of your model suggests that you represent the friendship as a node instead. Let each :Friendship node have [:MEMBER] relationships to two :User nodes. Then keep the friendship status as a property on that node. A good way to model relationship history could be to create a node for each update and keep these in a "linked list" that extends from the :Friendship node.

Community
  • 1
  • 1
jjaderberg
  • 9,844
  • 34
  • 34