【问题标题】:Neo4J Cypher Exclude nodes that connect to a specific nodeNeo4J Cypher 排除连接到特定节点的节点
【发布时间】:2016-09-21 01:48:43
【问题描述】:

我正在尝试查找未连接到特定节点的所有节点。我有一个应用程序,学生在做作业时会发现故事中的主题,然后写解释。然后,其他学生对这些解释进行同行评审。我的数据如下所示:

Assignment-hasTheme->Theme-hasChild->Theme
Annotation-theme->Theme
Explication-owner->User
Explication-annotation->Annotation
PeerReview-explication->Explication

作为应用程序的一部分,当用户必须进行同行评审时,我必须找到其他用户编写的所有说明。在我看来,这个查询应该可以工作:

MATCH
  (u),
  (a)-[:hasTheme]->(:Theme)
     -[:hasChild*]->(:Theme)
     <-[:theme]-(ann:Annotation)
     <-[:annotation]-(e:Explication)
OPTIONAL MATCH
  (e)<-[:explication]-(p:PeerReview)
WHERE id(a)=7 AND id(u)=4
  AND (e)-[:owner]->(u)
RETURN e, count(e) AS explicationCount
ORDER BY explicationCount ASC

问题在于它没有:我得到了所有用户写的所有说明。这包括用户写的说明。谁能告诉我如何排除这些?

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    问题在于WHERE 子句仅与另一个子句相关联……前面的MATCHOPTIONAL MATCHWITH。在您的查询中,它与OPTIONAL MATCH 相关联。

    如果您知道这一点重新阅读您的查询,您会看到第一个 MATCH 没有 WHERE 子句,因此它匹配所有分配和所有用户,找到所有解释。

    然后它执行可选匹配以在给定分配和用户 ID 上匹配 :PeerReviews,其中解释所有者是具有给定 ID 的用户。 WHERE 只影响匹配的:PeerReviews(变量p)。

    我可以看到其他几件事...您在模式中匹配的:Annotations 上引入了一个变量ann,并为:PeerReview 引入了一个变量p,但你不是实际上在查询中对这些做任何事情。这也使您的OPTIONAL MATCH 无用,您没有返回或对匹配的:PeerReviews 进行操作。

    我的建议是删除这些变量并完全删除您的OPTIONAL MATCH

    MATCH
      (u),
      (a)-[:hasTheme]->(:Theme)
         -[:hasChild*]->(:Theme)
         <-[:theme]-(:Annotation)
         <-[:annotation]-(e:Explication)
    WHERE id(a)=7 AND id(u)=4
      AND (e)-[:owner]->(u)
    RETURN e, count(e) AS explicationCount
    ORDER BY explicationCount ASC
    

    如果您确实想添加OPTIONAL MATCH 并使用匹配的:PeerReview,请确保它低于WHERE 影响MATCH,如下所示:

    MATCH
      (u),
      (a)-[:hasTheme]->(:Theme)
         -[:hasChild*]->(:Theme)
         <-[:theme]-(:Annotation)
         <-[:annotation]-(e:Explication)
    WHERE id(a)=7 AND id(u)=4
      AND (e)-[:owner]->(u)
    OPTIONAL MATCH
      (e)<-[:explication]-(p:PeerReview)
    RETURN e, count(e) AS explicationCount, p
    ORDER BY explicationCount ASC
    

    编辑

    为了响应期望结果是每个:Explication 和所有链接的计数:PeerReviews 的 cmets,您将使用以下查询:

    MATCH
      (u),
      (a)-[:hasTheme]->(:Theme)
         -[:hasChild*0..]->(:Theme)
         <-[:theme]-(:Annotation)
         <-[:annotation]-(e:Explication)
    WHERE id(a)=7 AND id(u)=4
      AND (e)-[:owner]->(u)
    OPTIONAL MATCH
      (e)<-[:explication]-(p:PeerReview)
    RETURN e, count(p) as peerReviewCount
    ORDER BY peerReviewCount ASC
    

    编辑

    更新了上面的查询,所以它会在父主题上找到注释,而不仅仅是它的子主题。

    【讨论】:

    • 谢谢!我不敢相信我没有尝试过。我想我从 Cypher 文档中误解了——我认为 WHERE 适用于所有 MATCH 子句。额外的变量是我想在查询中做的一些额外事情的结果。此外,我对 OPTIONAL MATCH 的目标与计算每个解释的评论数量有关(这是我在这里遗漏的内容)。
    • 这是一个相当普遍的误解,当我开始使用 Cypher 时,我做了同样的假设。有一些类似的陷阱在文档中并不明显,只有在您开始创建自己的查询时才会遇到。
    • 另外一件事...你返回 ecount(e) 可能是个问题,因为它是每行一个 Explication,所以我认为每行的计数为 1。
    • 谢谢!我实际上是在尝试返回 e,以及链接到每个 e 的 p 的数量。这样做的正确方法是什么?
    • 我将此添加到我的答案中。希望有帮助!
    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-29
    相关资源
    最近更新 更多