1
votes

Lets say I have a user model, and post model and a comment model.

I have to create a weekly update email.

I'm interested in multiple different data points, such as new comments on a user's posts. New users in a user's "group", new posts by a user's friends, new comments on a post by a user's friend, etc.

I would like to only return if one or more of the queries has data.

Here is some pseudo cypher

MATCH
 (u:User)-->(friend:User)-->(friend_post:Post)-->(friend_post_comment:Comment)
 (u:User)-->(p:Post)-->(c:Comment)
WHERE
 c.created_at > ...
       ## new comments on users posts
 friend.created_at > ...
       ## This is friends who were created since ...
 friend_post.created_at > ...
       ## This is posts that were created since ... by ALL friends, not just new ones
 ...
      ## Other queries
RETURN
 u, collect(friend) as friends, collect(c) as new_comments, etc.;

Is this possible to do complex queries like this in cypher? Ideally I'd also like it where it collects users who match 1 or more criteria, but not a user who doesnt match any criteria.

Or is it better to break these into seperate queries and handle the logic outside of cypher?

1

1 Answers

0
votes

You should be able to do with using multiple OPTIONAL MATCH clauses. Make sure to match any WHERE clauses with each OPTIONAL MATCH:

MATCH (u:User)

OPTIONAL MATCH (u)-->(friend:User)
WHERE friend.created_at > {now}

OPTIONAL MATCH (u)-->(friend:User)-->(friend_post:Post)-->(friend_post_comment:Comment)
WHERE friend_post.created_at > {now}

OPTIONAL MATCH (u:User)-->(p:Post)-->(c:Comment)
WHERE c.created_at > {now}

WITH
  u,
  collect(friend) as friends,
  collect(friend_post_comment) AS new_fof_comments,
  collect(c) as new_comments;

WHERE length(friends) > 0 OR length(new_fof_comments) > 0 OR length(new_comments) > 0

RETURN *

etc...