Neo4j 为什么收集(某物)会改变返回其他未报告内容的结果?

Neo4j 为什么收集(某物)会改变返回其他未报告内容的结果?,neo4j,Neo4j,我注意到一些奇怪的行为,我不太明白。一个用户报告了他们丢失帖子的错误 每次删除完整查询的部分后,我就能够找出问题所在 这将返回正确的帖子: MATCH (author:User {user_id: { user_id }) MATCH (post:Post)<-[:AUTHOR]-(author) MATCH (post)-[:HAS_COMMENT]->(comment:Comment)<-[:AUTHOR]-(commentAuthor:User) WH

我注意到一些奇怪的行为,我不太明白。一个用户报告了他们丢失帖子的错误

每次删除完整查询的部分后,我就能够找出问题所在

这将返回正确的帖子:

  MATCH (author:User {user_id: { user_id })

  MATCH (post:Post)<-[:AUTHOR]-(author)

  MATCH (post)-[:HAS_COMMENT]->(comment:Comment)<-[:AUTHOR]-(commentAuthor:User)
  WHERE NOT author.user_id = commentAuthor.user_id

  WITH
    post,
    author

  RETURN post  // returns the expected result
^导致一些最近回复帖子的用户被抛出


更新:在了解到应用聚合可以改变顺序后,结果发现我认为丢失的帖子没有首先返回,而是在结果的中间,因此我只需确保最小查询聚合后的顺序:

MATCH (author:User {user_id: { user_id })

  MATCH (post:Post)<-[:AUTHOR]-(author)

  MATCH (post)-[:HAS_COMMENT]->(comment:Comment)<-[:AUTHOR]-(commentAuthor:User)
  WHERE NOT author.user_id = commentAuthor.user_id

  WITH
    post,
    comment,
    author,
    collect(commentAuthor) as commentAuthors

  RETURN post

  ORDER BY comment.createdAt DESC  // now gives me the expected result
^两次尝试都给出了正确的post顺序,但计数不正确

最后,我要做的是:

---
Tom replied to 'your post'
1 hr ago  // based on time of Tom's latest comment in 'your post' (post.commentAuthor.commentCreatedAt)
3 participants | 3 comments
---
Erin replied to 'your other post'
2 hrs ago
5 participants | 6 comments
---
Kate replied to 'your post'
3 hrs ago
3 participants | 3 comments
---

* Tom may have also commented on 'your post' 1.5 hrs ago
but we only get the latest reply, which was 1 hr ago

好的,有了明确的要求,我们希望每个评论作者在每个帖子上都有自己的一行,以及每个帖子的参与者和评论数量

我们很接近了,但是我们要么在匹配到评论作者之前计算每个帖子的评论数量和参与者人数(可能通过使用模式理解),要么在最后放松我们的评论作者并在那里执行排序

让我们尝试第二种方法,不管怎样,您使用“展开”的方法是正确的

编辑

我们还将根据您在注释中的请求,限制并收集()最后的行

MATCH (author:User {user_id: { user_id }})

MATCH (post:Post)<-[:AUTHOR]-(author)
WHERE post.createdAt < { before } AND post.text =~ { keyword }

// removing labels for now since the relationships should be enough
// to match to the right nodes
MATCH (post)-[:HAS_COMMENT]->(comment)<-[:AUTHOR]-(commentAuthor)
WHERE author <> commentAuthor

WITH
 post,
 author,
 commentAuthor,
 count(comment) as commentsPerCommenter,
 max(comment.createdAt) as commentCreatedAt

WITH
 post,
 author,
 sum(commentsPerCommenter) as commentsCount,
 collect(commentAuthor {.*, commentCreatedAt}) as commentAuthors

WITH
 post,
 author,
 commentsCount,
 size(commentAuthors) as participantsCount,
 commentAuthors

UNWIND commentAuthors as commentAuthor

WITH
 post,
 author,
 commentsCount,
 participantsCount,
 commentAuthor

ORDER BY commentAuthor.commentCreatedAt DESC
LIMIT 11 // adjust as needed

RETURN collect(post { .*, author, commentAuthor, commentsCount, participantsCount, notificationType: 'reply' }) as postReplies
MATCH(作者:用户{User\u id:{User\u id})

MATCH(post:post)(comment)尝试对两个查询使用
RETURN DISTINCT post
,并让我们知道它们之间的比较情况(仅在您正在比较的第一个查询中确实需要…,第二个查询使用COLLECT(),由于聚合,已经具有不同的值)@InverseFalcon
返回不同的post
似乎对两个查询都没有影响。请记住,添加聚合时,顺序可能会改变。我希望第一个查询会有重复的帖子(应该在该查询结束时使用
returndistinct
将其剔除)。当您返回不同的帖子时,这两个查询的帖子计数是什么样子的?第一个查询没有distinct-83记录,第一个查询有distinct-8记录(但结果正确),第二个查询没有distinct-8记录(但结果不正确),第二个查询有distinct-8记录(但结果不正确)您是正确的。我浏览了第二个查询结果,我希望第一个显示的是中间。事实证明,真正的问题是,在完整查询中,它似乎没有按照
commentCreatedAt DESC
正确排序。好的,这是有意义的。对于第二个最小查询,它只需要在末尾添加一个
orderbycomment.createdAt DESC
,以确保顺序。但是,对于完整查询,似乎需要在
展开之前对其进行排序,但这样做会使计数为1-1,正如我们在前面的问题中发现的那样:让我用一些发现来更新我的帖子,因为我不确定如何将其应用到更复杂的查询中,我认为基本上必须在
展开之前进行
排序
。太棒了,它可以工作了!为了把它变成一个收藏,这没什么不对的,对吧?通过post、author、commentsCount、ParticipantScont、commentAuthor按commentAuthor排序将commentAuthors作为commentAuthor展开。commentCreatedAt DESC返回收集(post{.*,author,commentAuthor,commentsCount,ParticipantScont,notificationType:'reply'})[0..11]嗯,因此一般来说,如果我只想返回一个事物列表,那么返回事物的行/记录,而不是一个事物集合,这是一种更好的做法吗?我一直在收集,因为它返回一个数组[]。。。这对我来说更有意义/在发送到客户端并用JavaScript呈现时更容易使用。我可能说错了(删除了我的最后一条评论),这可能会起作用。看看结果是否有意义。虽然你可能想在期末考试后,在你采集之前,而不是在采集的片段中进行限制是的,结果是有意义的。谢谢你一直是我的Neo4j救世主。这对我来说真的很重要。没问题!这绝对是一个非琐碎的问题,很高兴我们能为您解决。更新了查询,将您的返回包含在COLLECT()中,尽管我使用了限制而不是获取集合的一部分。
  MATCH (post)-[:HAS_COMMENT]->(comment:Comment)<-[:AUTHOR]-(commentAuthor:User)
  WHERE NOT author.user_id = commentAuthor.user_id

  WITH
    post,
    author,
    commentAuthor,
    max(comment.createdAt) as commentCreatedAt,
    count(comment) as commentsPerCommenter

  WITH
    post,
    author,
    sum(commentsPerCommenter) as commentsCount,
    commentCreatedAt,
    collect(commentAuthor {.*, commentCreatedAt}) as commentAuthors ORDER BY commentCreatedAt DESC
---
Tom replied to 'your post'
1 hr ago  // based on time of Tom's latest comment in 'your post' (post.commentAuthor.commentCreatedAt)
3 participants | 3 comments
---
Erin replied to 'your other post'
2 hrs ago
5 participants | 6 comments
---
Kate replied to 'your post'
3 hrs ago
3 participants | 3 comments
---

* Tom may have also commented on 'your post' 1.5 hrs ago
but we only get the latest reply, which was 1 hr ago
MATCH (author:User {user_id: { user_id }})

MATCH (post:Post)<-[:AUTHOR]-(author)
WHERE post.createdAt < { before } AND post.text =~ { keyword }

// removing labels for now since the relationships should be enough
// to match to the right nodes
MATCH (post)-[:HAS_COMMENT]->(comment)<-[:AUTHOR]-(commentAuthor)
WHERE author <> commentAuthor

WITH
 post,
 author,
 commentAuthor,
 count(comment) as commentsPerCommenter,
 max(comment.createdAt) as commentCreatedAt

WITH
 post,
 author,
 sum(commentsPerCommenter) as commentsCount,
 collect(commentAuthor {.*, commentCreatedAt}) as commentAuthors

WITH
 post,
 author,
 commentsCount,
 size(commentAuthors) as participantsCount,
 commentAuthors

UNWIND commentAuthors as commentAuthor

WITH
 post,
 author,
 commentsCount,
 participantsCount,
 commentAuthor

ORDER BY commentAuthor.commentCreatedAt DESC
LIMIT 11 // adjust as needed

RETURN collect(post { .*, author, commentAuthor, commentsCount, participantsCount, notificationType: 'reply' }) as postReplies