2016-11-19 110 views
1

我有一个图,其中我有以下结构的结果:Neo4j的Cypher支架的查询:萨姆两个查询

Sample graph

节点:

  1. (BLUE) - >按照所有者关系,将页面附加到讲座节点和讲座中。
  2. 讲座系列(紫色) - >连接lectureSeries的由seriesof关系
  3. 讲座(GREEN)讲授 - 如上所述连接到页面和lectureSeries的>讲座。讲座有财产作为公共,追随者,私人和特权 其中一个讲座即lect1通过特权与用户连接。
  4. 用户(RED)(这里命名为Ann) - 它通过以下关系连接到页面,并连接到上面提到的1个讲座。

初始条件:

我们必须始终为用户显示所有的公共和跟随者的演讲,我们有没有问题,我们得到所需要的结果的完美查询。

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

我制作的基于你的身材的例子数据集。 (提示:您可以从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
  • 请务必携带节点nWITH条款,不然你会在下面的比赛了新n变量
+0

请小心使用WITH并保留查询中较早部分的变量范围。你的可选匹配与变量'n'相匹配,但是'n'不在范围内,因为它没有被带入WITHs ...'n'而是绑定到通过':seriesof'关系连接的任何东西讲座,它只是工作得很好,因为在您的示例数据集中只有一个':lectureseries'。 – InverseFalcon

+0

编辑后的查询完成了这个技巧。现在看起来很不错。 – InverseFalcon

+0

@InverseFalcon:谢谢你指出。 –

0

新的问题(感谢InverseFalcon): -Solved自己公布为他人谁可能像我一样陷入困境。

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