【问题标题】:Neo4j Cypher Query based on related node's property. Get node with max property valueNeo4j Cypher Query 基于相关节点的属性。获取具有最大属性值的节点
【发布时间】:2017-10-04 17:56:36
【问题描述】:

我有以下结构:

(A)-[:many]->(B)-[:also_many]->(C)

B 有一个名称属性。 C 有一个日期属性。 A 有很多 B 相关,而且每个 B 有很多 C 相关。

我想获得唯一的BC,其中c.date 是最高的。

日期存储如下:“YYYY-MM-DD HH:MM:SS”。我正在使用apoc.date.parse(date) 来获取时间戳值。

实在想不通怎么做。

样本数据集:

create (o:A {outlet: "SFO"}), (a:B {name: "Varun", date: "2017-04-01 00:00:00"}), (b:B {name: "Karen", date: "2017-04-12 00:00:00"}), (c:B {name: "Vicky", date: "2017-06-01 00:00:00"}), (aa:C {date: "2017-09-8 00:00:00", tag_no: "R2017123"}), (ab:C {date: "2017-09-02 00:00:00", tag_no: "R2017321"}), (ac:C {date: "2017-09-10 00:00:00", tag_no: "R2017423"}), (ad:C {date: "2017-09-23 00:00:00", tag_no: "R2017523"}), (ae:C {date: "2017-09-10 00:00:00", tag_no: "R2017930"}), (ba:C {date: "2017-09-02 00:00:00", tag_no:"R2017928"}), (bb:C {date: "2017-09-15 00:00:00", tag_no:"R2017039"}), (bc:C {date: "2017-09-10 00:00:00", tag_no:"R2017837"}), (bd:C {date: "2017-09-08 00:00:00", tag_no:"R2017022"}), (be:C {date: "2017-09-10 00:00:00", tag_no:"R2017883"}), (ca:C {date: "2017-09-11", tag_no:"R2017827"}), (cb:C {date: "2017-09-18", tag_no:"R2017322"}), (cc:C {date: "2017-09-21", tag_no:"R2017122"}), (cd:C {date: "2017-09-16", tag_no:"R2017877"}), (ce:C {date: "2017-09-08", tag_no:"R2017930"}), (o)-[:owns]->(a),(o)-[:owns]->(b),(o)-[:owns]->(c),(a)-[:subs]->(aa),(a)-[:subs]->(ab),(a)-[:subs]->(ac),(a)-[:subs]->(ad),(a)-[:subs]->(ae),(b)-[:subs]->(ba),(b)-[:subs]->(bb),(b)-[:subs]->(bc),(b)-[:subs]->(bd),(b)-[:subs]->(be),(c)-[:subs]->(ca),(c)-[:subs]->(cb),(c)-[:subs]->(cc),(c)-[:subs]->(cd),(c)-[:subs]->(ce);

我需要两个查询:

我想通过B.date 返回日期在2014-04-012014-05-01 内的B 节点以及每个B 节点的最新相关C 节点。在数据集中,我有两个 C 节点,它们具有相同的 date。但是查询应该只返回每个B 节点的一个结果。

第二个查询是:

返回日期在上述值范围内的 B 节点,这些节点没有日期范围内的 C 节点,例如“2017-09-01”和“2017-09-09”。

【问题讨论】:

  • 为什么需要APOC?这种格式的日期可以按字典顺序排序,因此ORDER BY c.date DESC LIMIT 1 应该为您提供最大值。当然,如果您想使用该日期,则必须对其进行解析,但您可以在应用程序代码中执行此操作。
  • 我尝试使用 max() 函数,但此日期格式不兼容。
  • 什么是“按字典顺序”?这对我来说是一个新名词。有没有一个函数可以获取几个节点的最高日期?
  • 对于lexicographically,请考虑按字母顺序排列。虽然我不推荐它,但max() 函数也应该可以工作:WITH ['2015-07-16 17:07:21', '2017-10-04 14:26:19'] AS xs UNWIND xs AS x RETURN max(x)(但要获得具有最高值的实际图形节点会更加困难)。
  • 此查询回答了您的第一个问题? MATCH (b:B)-[:subs]->(c:C) WHERE b.date >= "2017-04-01" and b.date <= "2017-04-15" WITH b as b, max(c.date) as cs RETURN b, cs

标签: neo4j cypher


【解决方案1】:

我想返回日期在 2014 年 4 月 1 日和 2014-05-01 和B.date 为每个B 节点的最新相关C 节点。在 数据集,我有两个具有相同日期的 C 节点。但查询 每个 B 节点应该只返回一个结果。

这应该可行:

MATCH (b:B)-[:subs]->(c:C)
// filter b nodes by date range
WHERE b.date >= "2017-04-01" and b.date <= "2017-04-15"
// store c nodes into collection and get the max date for c nodes
// grouped by b
WITH b as b, collect(c) as cs, MAX(c.date) as maxDate
// return b, filtering only c nodes that date are equals to maxDate
// getting only the first filtered 
return b, filter(c in cs WHERE c.date = maxDate)[0]

返回日期在上述值范围内的 B 个节点,这些节点没有 C 日期在日期范围内的节点,例如“2017-09-01”和“2017-09-09”。

还有这个:

MATCH (b:B)-[:subs]->(c:C)
WHERE (b.date >= "2017-04-01" and b.date <= "2017-04-15")
AND (c.date <= "2017-09-01" and c.date >= "2017-09-09")
RETURN b

【讨论】:

  • 不。对于每个 B 节点,我需要该 B 节点的所有相关 C 节点中具有最高日期的 C 节点。
  • @notANerdDev 你能分享一个样本数据集吗?这种方式会更容易为您提供帮助。
  • 好的。给我一点时间。我将编写一个密码查询来为您创建一个示例数据集。非常感谢。
  • 已添加。谢谢您的帮助。试图解决这个问题太久了。
  • @notANerdDev 更新了我的答案。请看一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多