2017-04-24 146 views
1

我正在创建一个类似社交媒体的平台,它有一个家庭饲料。主页包含帖子,可以有任何数量的评论和喜欢。评论也可以有任何数量的喜好。如何限制neo4j中的特定节点?

当用户第一次加载家庭饲料时,我想首先获取一定数量的帖子(为10)。我目前正在运行的查询如下:

MATCH (p:Post)<-[:POSTED]-(u1:User), (u2: User {id: {id}}) 
WHERE u1.id = {id} OR (u1)-[:FRIENDS_WITH]-(u2) 
OPTIONAL MATCH (u4:User)-[:LIKES]->(p) 
OPTIONAL MATCH (u3:User)-[:COMMENTED]->(c:Comment)<-[:HAS_COMMENT]-(p) 
OPTIONAL MATCH (u5:User)-[:LIKES]->(c) 
RETURN p, u1, u3, c, u4, u5 ORDER BY p.timestamp DESC LIMIT 10 

的这里的问题是,它只能获取10个结果,不一定是10个职位。我想要一种专门收集10个帖子的方法,然后在每个帖子上获取所有评论/喜欢/评论喜欢。这可能在一个单一的查询?

回答

1

这可能会做你的原意:

MATCH (p:Post)<-[:POSTED]-(u1:User), (u2: User {id: {id}}) 
WHERE u1.id = {id} OR (u1)-[:FRIENDS_WITH]-(u2) 
WITH p, u1 
ORDER BY p.timestamp DESC 
LIMIT 10 
OPTIONAL MATCH (u4:User)-[:LIKES]->(p) 
OPTIONAL MATCH (u3:User)-[:COMMENTED]->(c:Comment)<-[:HAS_COMMENT]-(p) 
OPTIONAL MATCH (u5:User)-[:LIKES]->(c) 
RETURN p, u1, u3, c, u4, u5; 

它可以确保10个职位被挑选是最近的。

它做出了合理的假设,即每Post由1个用户发布(因此WITH子句可以简单地代替WITH p, COLLECT(u1)之类的东西)。

+0

谢谢!我不知道你可以在查询的其余部分之前使用limit子句。 – singwukgwu

0

如果您在匹配帖子上的评论前先限制帖子匹配,那么您应该能够得到你想要的。像这样的事情应该让你去。

MATCH (p:Post)<-[:POSTED]-(u1:User), (u2: User {id: {id}}) 
WHERE u1.id = {id} OR (u1)-[:FRIENDS_WITH]-(u2) 
WITH p, u1 
LIMIT 10 
OPTIONAL MATCH (u4:User)-[:LIKES]->(p) 
OPTIONAL MATCH (u3:User)-[:COMMENTED]->(c:Comment)<-[:HAS_COMMENT]-(p) 
OPTIONAL MATCH (u5:User)-[:LIKES]->(c) 
RETURN p, u1, u3, c, u4, u5 
ORDER BY p.timestamp DESC 
+0

感谢您的回答!我得到它的工作:) – singwukgwu

2

是的,这是可能的。我们只需要在查询中尽早移动LIMIT来限制帖子,并且只有在限制后才能开始执行这些可选匹配。

您可能还需要阅读WITH子句(用于划分查询的一部分)和COLLECT()函数,以将行收集到单个列表中。

我们还可以使用0..1的可变长度关系来改进初始匹配,以便始终将起始节点包含在与u1的匹配中。

在某些情况下,我们也可以使用pattern comprehension而不是可选匹配来执行匹配并收集列表中的结果。

MATCH (post:Post)<-[:POSTED]-(poster:User)-[:FRIENDS_WITH*0..1]-(:User {id: {id}}) 
WITH post, poster 
ORDER BY post.timestamp DESC LIMIT 10 
WITH post, poster, [(u:User)-[:LIKES]->(post) | u] as usersWhoLiked 
// each post, poster, and collection of liking users on a row 
OPTIONAL MATCH (commenter:User)-[:COMMENTED]->(comment:Comment)<-[:HAS_COMMENT]-(post) 
// now for each comment on a row, collect users who liked the comment 
WITH post, poster, usersWhoLiked, comment, commenter, [(u:User)-[:LIKES]->(comment) | u] as commentLikers 
RETURN post, poster, usersWhoLiked, comment, commenter, commentLikers 

这会给你每个帖子的评论(和评论者,以及那些喜欢评论者的列表)。帖子,海报和usersWhoLiked列表将与每个相关评论一起显示。

如果你想收集的意见太多,所以只会有每行一个职位,那么需要改变的查询结束。你会需要更换RETURN行:

... 
// now for each post on a row, collect the comments, commenter, and likers per comment 
WITH post, poster, usersWhoLiked, collect(comment {.*, commenter, commentLikers}) as comments 
RETURN post, poster, usersWhoLiked, comments 

这是使用map projection输出,为每个评论,地图注释的属性,以及添加了评论者的地图,并且用户的列表谁喜欢评论。