Search code examples
graph-databasesgremlinamazon-neptune

Graph/Gremlin query for social media use case


Mine is a social network kind scenario. I want to get all the posts 'posted' by the people I follow. For each of these posts I want to know whether I have liked it or not and also the no of likes and comments that post have(only count) and latest 3 comments with all properties and all the properties of the commented user like his name etc. What is the best solution to get this in gremlin (possibly avoiding duplication)?

g.addV('user').property('id',1).as('1').
  addV('user').property('id',2).as('2').
  addV('user').property('id',3).as('3').
  addV('user').property('id',4).as('4').
  addV('post').property('postId','post1').as('p1').
  addV('post').property('postId','post2').as('p2').
  addV('comment').property('id','c1').property('text','hi').as('c1'). 
  addV('comment').property('id','c2').property('text','nice').as('c2'). 
  addV('comment').property('id','c3').property('text','hello').as('c3'). 
  addE('follow').from('1').to('2').
  addE('follow').from('1').to('3').
  addE('follow').from('1').to('4').
  addE('posted').from('2').to('p1').
  addE('posted').from('2').to('p2').
  addE('liked').from('1').to('p2').
  addE('liked').from('3').to('p2').
  addE('liked').from('4').to('p2').
  addE('commented').from('1').to('c1'). 
  addE('comments').from('c1').to('p1'). 
  addE('commented').from('2').to('c2'). 
  addE('comments').from('c2').to('p2').iterate()

Solution

  • The commented edges should have a timestamp property, that's why the following query still has the todo in it, but I guess it should be easy to figure the remaining part out yourself.

    g.V().has('user','id',1).as('me').
      out('follow').as('friend').
      out('posted').as('post').                                     /* all the posts 'posted' by the people I follow */
      project('friend','post','liked','likes','comments','latest').
        by(select('friend')).
        by(select('post').by('postId')).
        by(coalesce(__.in('liked').where(eq('me')).constant('yes'),
                    constant('no'))).                               /* whether I have liked it or not                */
        by(inE('liked').count()).                                   /* no of likes                                   */
        by(inE('comments').count()).                                /* comments that post have(only count)           */
        by(__.in('comments').as('comment').                         /* todo: order by time desc                      */
           in('commented').as('user').limit(3).                     /* latest 3 comments                             */
           select('comment','user').
             by(valueMap()).                                        /* with all properties                           */
           fold())
    

    Result for the sample graph:

    ==>[friend:v[2],post:post1,liked:no,likes:0,comments:1,latest:[[comment:[id:[c1],text:[hi]],user:[id:[1]]]]]
    ==>[friend:v[2],post:post2,liked:yes,likes:3,comments:1,latest:[[comment:[id:[c2],text:[nice]],user:[id:[2]]]]]