繁体   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