Neo4j Cypher查询:求和两个查询的结果

时间:2016-11-19 06:23:56

标签: java neo4j cypher

我有一个图表,其中我有以下结构:

Sample graph

节点

  1. Page (蓝色) - >页面由关系所有者附加到讲座节点和讲座。
  2. 讲座系列(PURPLE) - >通过系列关系与讲座相关的讲座系列
  3. 讲座(绿色) - >与上面提到的页面和讲座系列相关的讲座。讲座有公共财产,追随者,私人和特权 其中一个讲座即lect1通过特权的实现与用户连接。
  4. 用户(RED)(此处名为Ann) - 按照以下关系连接到上面的1个讲座。
  5. 初始条件:

    我们必须向用户展示所有公众和跟随者讲座,因为我们有完美的查询,没有问题,我们得到了所需的结果。

    MATCH
      (o:page{name:'engg'})-[r:ownerof]-(n:lectureseries)-[s:seriesof]-(l:lecture)
    WHERE l.privacy='public' or l.privacy='follower'
    RETURN DISTINCT n.name as name,n.series_name as title, COUNT(l) AS lecturecount
    

    结果:

    name    lecturecount
    
    java    2 (lect3, lect4)
    

    问题:现在,我们必须在计数中添加这些讲座,如果权限讲座通过关系特权

    与用户相关联

    我尝试了这个查询:

    OPTIONAL MATCH (o:page {name:'engg'})-[r:ownerof]-(n:lectureseries)-[s:seriesof]-(l:lecture)
    WHERE l.privacy='public' or l.privacy='follower'
    RETURN DISTINCT n.name as name, COUNT(l) AS lecturecount
    UNION
    OPTIONAL MATCH (o:page {name:'engg'})-[r:ownerof]-(n:lectureseries)-[s:seriesof]-(l:lecture)-[:privileged]-(u:user {name:'Ann'})
    RETURN DISTINCT n.name as name, COUNT(l) AS lecturecount
    

    结果:

    name    lecturecount
    
    java    2
    
    java    1
    

    但结果应该是一行:java,3

    我搜索了很多,最后是UNION条款,但它没有帮助。

    新问题:

    如何将结果总结为

    seriesname  lecturecount             seriescount    lecturecount
    
    java    2                      AS      2             3
    dotnet  1
    

2 个答案:

答案 0 :(得分:2)

我根据你的身材制作了一个示例数据集。 (提示:您可以从Neo4j Web UI导出CSV并将其包含在问题中。)

CREATE
  (lect1:lecture {name:"lect1"}),
  (lect3:lecture {name:"lect3", privacy: "public"}),
  (lect4:lecture {name:"lect4", privacy: "follower"}),
  (lect5:lecture {name:"lect5"}),
  (engg:page {name:"engg"}),
  (Ann:user {name:"Ann"}),
  (java:lectureseries {series_name:"java"}),
  (engg)-[:ownerof]->(lect1),
  (engg)-[:ownerof]->(lect3),
  (engg)-[:ownerof]->(lect4),
  (engg)-[:ownerof]->(lect5),
  (Ann)-[:follows]->(engg),
  (Ann)-[:privileged]->(lect1),
  (java)-[:seriesof]->(lect1),
  (java)-[:seriesof]->(lect3),
  (java)-[:seriesof]->(lect4),
  (java)-[:seriesof]->(lect5),
  (engg)-[:ownerof]->(java)

查询:

MATCH (:page {name:'engg'})-[:ownerof]->(n:lectureseries)
OPTIONAL MATCH (n)-[:seriesof]->(l1:lecture)
WHERE l1.privacy='public' or l1.privacy='follower'
WITH n, COUNT(l1) as lecturecount1
OPTIONAL MATCH (n)-[:seriesof]->(l2:lecture)<-[:privileged]-(:user{name:'Ann'})
RETURN n.series_name as name, lecturecount1 + COUNT(l2) AS lecturecount

WITH构造允许您将查询链接在一起。

结果:

╒════╤════════════╕
│name│lecturecount│
╞════╪════════════╡
│java│3           │
└────┴────────────┘

几句话:

  • 在查询中使用有向边。它在性能方面没有很好的影响,但它提高了可读性。
  • 您不必为以后未使用的变量命名。出于这个原因,我删除了or变量。
  • 根据Cypher styleguide,所有关键字都应为大写。
  • 除非页面与其讲座系列之间有多个ownerof边缘,否则无需使用DISTINCT
  • 确保您在n子句中携带节点WITH,否则您将在以下匹配中获得新的n变量(感谢InverseFalcon。)

答案 1 :(得分:0)

新问题: - 我自己发布了可能会像我这样的人。

Match (o:page{name:'engg'}) 
with o 
optional match (o)-[:ownerof]-(ls:lectureseries)-[:seriesof]-(l:lecture) 
where l.privacy='public' or l.privacy='follower' 
with o ,count(distinct(ls)) as lscount,count(l) as lecount
optional match (o)-[:ownerof]-(ls)-[:seriesof]-(l1:lecture)-[:privileged]-(u:user{name:'Ann'})
RETURN lscount as lectureseriescount,lecount+count(l1) as lecturecount