[英]Neo4j - Complex cypher query - needs outer join
我正在使用Neo4j圖形數據庫,我正在嘗試構建一個復雜的密碼查詢
我有以下節點和關系:
節點 :
關系 :
我想了解有資格獲得某個品牌新預訂的客戶數量 。
因此,我需要計算給定品牌的每位客戶的預訂,並與此客戶的細分市場的MaxReservationsPerBrandPerMonth進行比較。
請注意,沒有預訂的客戶也應計算在內
謝謝你的支持。
編輯1
在嘗試邁克爾第一次查詢后,查詢是:
PROFILE MATCH (c:Customer)
// also count customers without reservations (make this match optional)
OPTIONAL MATCH (c)-[:CUST_RESERVED]->(r:Reservation)-[:RESERVATION_FOR]->(b:brand {BRAND_ID: "3"})
// count reservations by brand and customers
WITH c, b, count(*) as reservations
MATCH (c)-[:SEGMENTED]->(s:segment)
WHERE reservations < s.max_sms_per_month
// aggregate count customers per brand
RETURN b.NAME, count(distinct c) as customers
查詢結果:
結果是出乎意料的,我想獲得“本田”品牌的合格客戶,結果只有5(之前已經為本田保留,但仍然符合條件,因為他們沒有達到最大值),結果應該是998734(所有客戶)
查詢檔案: 查詢檔案
編輯2
邁克爾第二次查詢在大約20秒內就像一個魅力,謝謝邁克爾我需要包含一些日期邏輯來檢查某些預訂期間的預訂請:)
您已將其拼寫出來,請參閱我們的在線指南,了解您如何處理用例問題: http : //neo4j.com/developer/guide-data-modeling/
所以你的模式是
(:Customer)-[:IS_SEGMENTED]->(:Segment {MaxReservationsPerBrandPerMonth:int})
(:Customer)-[:HAS_RESERVED]->(:Reservation)
(:Reservation)-[:FOR_BRAND]->(:Brand)
你的問題:
- 我想了解有資格獲得某個品牌新預訂的客戶數量。
- 因此,我需要計算給定品牌的每位客戶的預訂,並與此客戶的細分市場的MaxReservationsPerBrandPerMonth進行比較。
- 請注意,沒有預訂的客戶也應計算在內
MATCH (c:Customer)
// also count customers without reservations (make this match optional)
OPTIONAL MATCH (c)-[:HAS_RESERVED]->(r:Reservation)-[:FOR_BRAND]->(b:Brand)
// count reservations by brand and customers
WITH c, b, count(*) as reservations
MATCH (c)-[:IS_SEGMENTED]->(s:Segment)
WHERE s.MaxReservationsPerBrandPerMonth < reservations
// aggregate count customers per brand
RETURN b.name, count(distinct c) as customers
“如果客戶無需預訂就應該算什么”為0?
問題:沒有預訂的客戶與哪些品牌相關/反對? 由於reservations-count為0,那么MaxReservationsPerBrandPerMonth必須為-1才能被選中? 所以我們也可以讓它不可選? 還請與PROFILE前綴共享您獲得的查詢計划。
MATCH (c:Customer)-[:HAS_RESERVED]->(r:Reservation)-[:FOR_BRAND]->(b:Brand)
// count reservations by brand and customers
WITH c, b, count(*) as reservations
MATCH (c)-[:IS_SEGMENTED]->(s:Segment)
WHERE s.MaxReservationsPerBrandPerMonth < reservations
// aggregate count customers per brand
RETURN b.name, count(distinct c) as customers
您的查詢是全局圖形,因此它將觸及許多路徑,您已經擁有至少10M db-hits。
我可能會稍微更改一下這個查詢:
雖然品牌如何在這里發揮作用,但我不是百分之百確定:沒有數據集也有點困難!
MATCH (b:brand {BRAND_ID: "3"})
MATCH (c:Customer)
WITH b,c, size((c)-[:CUST_RESERVED]->()) as total_res
WITH b,c,total_res,
case when total_res > 0 then last(nodes(head((c)-[:SEGMENTED]->(:segment)))).max_sms_per_month else 10 end as max_sms_per_month,
case when total_res > 0 then size((c)-[:CUST_RESERVED]->()-[:RESERVATION_FOR]->(b)) else 0 end as brand_res
WHERE total_res = 0 OR total_res < max_sms_per_month OR brand_res < max_sms_per_month
// TODO what to do with reservations by brand?
RETURN b.NAME, count(distinct c) as customers
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.