2016-11-19 96 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