其中之一是Cypher中沒有GROUP BY,因爲分組列在每一行中都隱含着非聚合列。
我假設你有約束和索引設置?您需要爲正式查詢正確設置這些設置。
我看到的一個主要的紅旗是在這些查詢中並沒有任何關係,並且可能在您的整個數據模型中。圖形數據庫被用來模擬事物之間的關係,並且這些往往取代關係數據庫中外鍵的概念。我會講更多更好的方法來最終建模數據。
這就是說,我會採取一個刺激,用你當前的數據模型來翻譯它。
我的做法是從內到外。首先讓我們獲取允許的store_id和b.product_id值的集合。
// first collect allowed STORE_IDs
MATCH (s:STORE)
WITH COLLECT(s.STORE_ID) as STORE_IDs
MATCH (e:FACT)
// now get PRODUCT_IDs with the most associated TICKET_IDs
WITH STORE_IDs, e.PRODUCT_ID, COUNT(DISTICT e.TICKET_ID) as TICKET_ID_CNT
ORDER BY TICKET_ID_CNT DESC
LIMIT 5000
WITH STORE_IDs, COLLECT(e.PRODUCT_ID) as PRODUCT_IDs
// we now have 1 row with both collections, and will do membership checking with them later
// next get only PRODUCT nodes with PRODUCT_ID in the collection of allowed PRODUCT_IDs
MATCH (b:PRODUCT)
WHERE b.PRODUCT_ID in PRODUCT_IDs
WITH b, STORE_IDs
// now get FACT nodes with STORE_ID in the collection of allowed STORE_IDs
// and associated with PRODUCT nodes by PRODUCT_ID
MATCH (a:FACT)
WHERE a.STORE_ID in STORE_IDs
AND a.PRODUCT_ID = b.PRODUCT_ID
WITH a, b
// grouping is implicit, the non-aggregation columns are the grouping key
WITH a.TICKET_ID as TICKET_ID, b.PRODUCT_ID as PRODUCT_ID, b.PRODUCT_DESC as PRODUCT_DESC, a.PROMOTION_FLAG as PROMOTION_FLAG, SUM(a.QUANTITY) as SUM_UNITS, SUM(a.SALES) as SUM_SALES
CREATE (:CALC_BASE {TICKET_ID:TICKET_ID, PRODUCT_ID:PRODUCT_ID, PRODUCT_DESC:PRODUCT_DESC, PROMO_FLAG:PROMOTION_FLAG, SUM_UNITS:SUM_UNITS, SUM_SALES:SUM_SALES})
這應該讓你得到你想要的。
現在回到所有這些的主要問題......您正在使用圖形數據庫來處理非圖形數據和查詢。您正在使用外鍵並試圖加入節點,而不是將它們建模爲關係。您還使用縮寫名稱,這使得很難弄清楚數據的含義以及它應該如何相互關聯。
我給你的建議是重新考慮你的數據模型,特別是你的數據如何連接在一起。尋找你使用外鍵加入的地方,而是考慮如何用你的節點之間的關係來替換它,並且結合這些關係的性質。
數據以更加面向圖的方式進行建模,具有更多面向圖形和性能的查詢,以及易於理解和與其他人交流的數據模型。
編輯
現在,你有不同類型的節點之間的關係,我們可以簡化查詢了一下。
該方法將是類似的,我們仍然會從內而外,而不是一些內部子查詢(雖然與Neo4j 3.1,pattern comprehension可以使用像內部查詢在各種情況下)。
// first get products with the most tickets (top 5k)
MATCH (f:FACT)
WITH f.PRODUCT_ID as productID, COUNT(DISTICT f.TICKET_ID) as ticketIDCnt
ORDER BY ticketIDCnt DESC
LIMIT 5000
MATCH (p:PRODUCT)
WHERE p.PRODUCT_ID = productID
WITH p
// with those products, get related facts (graph equivalent of a join)
MATCH (p)<-[:HAS_PRODUCT]-(f:FACT)
// ensure the fact has a related store.
// if ALL facts have a related store, you don't need this WHERE clause
WHERE (f)-[:HAS_STORE]->(:STORE)
WITH f.TICKET_ID as TICKET_ID, p.PRODUCT_ID as PRODUCT_ID, p.PRODUCT_DESC as PRODUCT_DESC, f.PROMOTION_FLAG as PROMOTION_FLAG, SUM(f.QUANTITY) as SUM_UNITS, SUM(f.SALES) as SUM_SALES
CREATE (:CALC_BASE {TICKET_ID:TICKET_ID, PRODUCT_ID:PRODUCT_ID, PRODUCT_DESC:PRODUCT_DESC, PROMO_FLAG:PROMOTION_FLAG, SUM_UNITS:SUM_UNITS, SUM_SALES:SUM_SALES})
同樣,您需要確保在數據模型中有合適的索引和唯一約束來加速匹配。
還有幾個方面你可能想要考慮修改你的數據模型(當然它有意義)。有一個票證ID的概念,但沒有:票證節點。您已創建:CALC_BASE節點,但未將它們與以下內容相關聯:產品或票證。一般來說,查看你仍在使用外鍵概念的地方是很有用的,並且看看把它們建模爲與其他節點的關係是否會更好。
再次在GROUP BY上,這是在Cypher中爲您處理的。您的行由非聚合列和聚合列組成。 Cypher自動將非聚合列用作分組鍵(相當於按這些列分組)。由於SUM_UNITS和SUM_SALES是作爲聚合函數的SUM()操作的結果,所有其他列將自動用作分組鍵。
歡迎來到堆棧溢出和圖形數據庫! :-)爲了利用圖形數據庫的強大功能,必須將連接映射到邊緣(或Neo4j中的_relationships_)。因此,如果'p_id'屬性上連接了'MYTABLE'和'TMP_P',則應該添加'(:MyTable) - [:REL] - >(:TmpP)'關係。 (請注意,按照慣例,節點標籤是CamelCase,關係是大寫的。)有關RDBMS開發人員的優秀指南:請參見本白皮書(https://neo4j.com/resources/rdbms-developer-graph-white-paper/) )和[post](https://neo4j.com/developer/guide-sql-to-cypher/)。 –