如何只限制neo4j中的特定节点?

时间:2017-04-24 21:03:00

标签: neo4j cypher

我正在创建一个具有家庭饲料的类似社交媒体的平台。主页包含帖子,其中可以包含任意数量的评论和喜欢。评论也可以包含任何数量的喜欢。

当用户首次加载主页时,我想首先只获取一定数量的帖子(为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个帖子,然后在每个帖子上获取所有评论/喜欢/评论喜欢。这可能在一个查询中吗?

3 个答案:

答案 0 :(得分:2)

是的,这是可能的。我们只需要在查询的前面移动LIMIT来限制帖子,只有在这些限制之后我们才能开始做那些可选的匹配。

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

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

在某些情况下,我们也可以使用pattern comprehension代替OPTIONAL MATCH来执行匹配并在列表中收集结果。

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

这将在一行中为您提供每个帖子评论(和评论者以及喜欢评论的人员列表)。帖子,海报和用户列表将显示每个相关评论。

如果您也想收集评论,那么每行只会有一个帖子,那么查询的结尾需要更改。您需要将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为每个评论输出评论属性的地图,以及将评论者添加到地图以及喜欢评论的用户列表。

答案 1 :(得分: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, u1而不是WITH p, COLLECT(u1)这样的内容

答案 2 :(得分:0)

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

ng2-izitoast