Graph Neo4j-复杂密码查询-需要外部联接
我正在使用Neo4j图形数据库,并试图构建一个复杂的密码查询 我有以下节点和关系: 节点:Graph Neo4j-复杂密码查询-需要外部联接,graph,neo4j,cypher,Graph,Neo4j,Cypher,我正在使用Neo4j图形数据库,并试图构建一个复杂的密码查询 我有以下节点和关系: 节点: 客户节点 品牌节点 段节点(具有“MaxReservationsPerBrandPerMonth”属性) 预订节点 关系: 每个客户都被细分为一个细分市场 客户可以与预订建立客户预订关系 每个预订都与一个品牌相关 我想获得符合某个品牌新预订条件的客户数 因此,我需要计算给定品牌的每位客户的预订数量,并与该客户细分市场的MaxReservationsPerBrandPerMonth进行比较 请注意,
- 客户节点
- 品牌节点
- 段节点(具有“MaxReservationsPerBrandPerMonth”属性)
- 预订节点
- 每个客户都被细分为一个细分市场
- 客户可以与预订建立客户预订关系
- 每个预订都与一个品牌相关
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
配置文件匹配(c:客户)
//还统计没有预订的客户(使此匹配成为可选)
可选匹配(c)-[:CUST_RESERVED]->(r:Reservation)-[:Reservation_FOR]->(b:brand{brand_ID:“3”})
//按品牌和客户统计预订数量
带c、b、计数(*)作为保留
匹配(c)-[:分段]->(s:分段)
其中预订
查询结果:
结果出乎意料,我想获得“本田”品牌的合格客户,结果只有5个(之前已经为本田保留了,但仍然合格,因为他们还没有达到最大值),结果应该是998734(所有客户)
查询配置文件:
数据集:
SQL中需要的查询:
编辑2
迈克尔第二个问题在20秒左右就成功了,谢谢你,迈克尔
我需要包括一些日期逻辑来检查特定预订期间的预订,请:)您已经详细说明了,请参阅我们的在线指南,了解如何解决您的用例问题: 所以你的模式是
(:Customer)-[:IS_SEGMENTED]->(:Segment {MaxReservationsPerBrandPerMonth:int})
(:Customer)-[:HAS_RESERVED]->(:Reservation)
(:Reservation)-[:FOR_BRAND]->(:Brand)
你的问题:
匹配(c:客户)
//还统计没有预订的客户(使此匹配成为可选)
可选匹配(c)-[:已保留]->(r:保留)-[:用于品牌]->(b:品牌)
//按品牌和客户统计预订数量
带c、b、计数(*)作为保留
匹配(c)-[:是分段的]->(s:分段)
其中s.MaxReservationsPerBrandPerMonth
“没有预订的客户应该算什么”为0
更新:查询非可选预订
问题:没有预订的客户会与哪个品牌相关/对照哪个品牌?由于保留计数为0,那么MaxReservationsPerBrandPerMonth必须为-1才能选择那些?所以我们也可以让它成为非可选的?还请使用配置文件前缀共享您获得的查询计划
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
MATCH(c:Customer)-[:HAS_RESERVED]->(r:Reservation)-[:FOR_BRAND]->(b:BRAND)
//按品牌和客户统计预订数量
带c、b、计数(*)作为保留
匹配(c)-[:是分段的]->(s:分段)
其中s.MaxReservationsPerBrandPerMonth
更新2,查询优化尝试
您的查询是一个图形全局查询,因此它将涉及许多路径,您已经有至少10MB的命中率
我可能会稍微改变一下这个问题:
我不再100%确定品牌是如何在这里发挥作用的:
没有数据集也有点困难
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
匹配(b:brand{brand_ID:“3”})
匹配(c:客户)
以b,c,size((c)-[:CUST_RESERVED]->())作为总分辨率
b,c,总分辨率,
当总分辨率>0时,则为最后一个(节点(头((c)-[:分段]->(:分段))。每个月的最大短消息数,否则10个月的最大短消息数,
当总分辨率>0时,则大小((c)-[:CUST\u RESERVED]->()-[:RESERVATION\u FOR]->(b))否则0以品牌分辨率结束
其中total_res=0或total_res
非常感谢你,Michael,它很有魅力,我只是把它改成了reservations:brand(brand\u ID)创建约束/索引
(注意,您应该修复
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