簡體   English   中英

Neo4j - 復雜的密碼查詢 - 需要外連接

[英]Neo4j - Complex cypher query - needs outer join

我正在使用Neo4j圖形數據庫,我正在嘗試構建一個復雜的密碼查詢

我有以下節點和關系:

節點

  • 客戶節點
  • 品牌節點
  • 段節點(具有“MaxReservationsPerBrandPerMonth”屬性)
  • 預訂節點

關系

  • 每個客戶都被細分為一個細分市場
  • 客戶可以有一個預留的cust_reserved關系
  • 每個預訂都品牌有關

我想了解有資格獲得某個品牌新預訂的客戶數量

因此,我需要計算給定品牌的每位客戶的預訂,並與此客戶的細分市場的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(所有客戶)

查詢檔案: 查詢檔案

數據集: 這里需要SQL中的查詢: 這里

編輯2

邁克爾第二次查詢在大約20秒內就像一個魅力,謝謝邁克爾我需要包含一些日期邏輯來檢查某些預訂期間的預訂請:)

您已將其拼寫出來,請參閱我們的在線指南,了解您如何處理用例問題: http//neo4j.com/developer/guide-data-modeling/

所以你的模式是

(:Customer)-[:IS_SEGMENTED]->(:Segment {MaxReservationsPerBrandPerMonth:int})
(:Customer)-[:HAS_RESERVED]->(:Reservation)
(:Reservation)-[:FOR_BRAND]->(:Brand)

你的問題:

  1. 我想了解有資格獲得某個品牌新預訂的客戶數量。
  2. 因此,我需要計算給定品牌的每位客戶的預訂,並與此客戶的細分市場的MaxReservationsPerBrandPerMonth進行比較。
  3. 請注意,沒有預訂的客戶也應計算在內
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

更新2,查詢優化嘗試

您的查詢是全局圖形,因此它將觸及許多路徑,您已經擁有至少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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM