【问题标题】:How to loop through properties for comparison for a certain type of node in Neo4j using Cypher如何使用 Cypher 在 Neo4j 中循环属性以比较特定类型的节点
【发布时间】:2019-09-27 22:38:38
【问题描述】:

我正在使用 Neo4j,想知道如何使用 Cypher 来遍历连接一个节点的其他节点的属性以进行比较并过滤满足条件的节点。

这里是示例数据:

Person Movie Publish_Date
Tina   A     2016-01-01
Tina   B     2016-01-01
Tina   C     2016-03-05
Tina   D     2016-03-06
Tina   X     2018-03-09  
Bob    E     2016-08-01
Bob    F     2016-08-08
Ana    G     2016-04-05
Ana    H     2016-08-05
Ana    I     2016-12-05

这就是我想要的:

Person Movie Publish_Date
Tina   A     2016-01-01
Tina   B     2016-01-01
Tina   C     2016-03-05
Tina   D     2016-03-06
Tina   X     2018-03-09   
Bob    E     2016-08-01
Bob    F     2016-08-08

我想退回参与30天内发行的2部电影以上的人和电影信息。

我的想法是对每个人,遍历与他连接的电影节点的发布日期,并将满足条件的保留在结果表中。

这是我获取示例数据的查询:

MATCH (p:Person)-[r1:ACTED_IN]->(m:Movie)
WITH p, m 
ORDER BY p.Name DESC, n.Publish_Date
RETURN p.name AS Person, m.title AS Movie, m.publish_date AS Publish_Date

请提出建议。

提前致谢!

【问题讨论】:

  • 你能澄清时间限制吗?这是在过去 30 天内发行的超过 2 部电影,还是在大约 30 天内发行的超过 2 部电影?重叠事件怎么样,比如电影 1 和 2 和 3 发生在 30 天的时间范围内,但电影 2 和 3 以及 4 和 5 也在 30 天的时间范围内?这是否意味着您也需要在此范围内更小的时间范围(2 和 3 和 4 也是如此)?
  • 您好,感谢您的提问!我想要在大约 30 天的时间内出版 2 部电影。对于您提到的重叠情况,我想要 1、2、3、4 和 5,因为它们都在至少 30 天内发布,另外还有 2 部电影
  • 您可能需要稍微调整一下您的数据和结果,因为不应返回此条目Tina X 2018-03-09 ,因为它是在2016-03-06上的上一部电影几年后发布的
  • 您可能还想调整您的要求,因为您要返回 Bob 和两部电影,但您指定了 in more than 2 movies published in 30 days。您的意思是“30 天内至少发行 2 部电影”?

标签: neo4j cypher graph-databases


【解决方案1】:

我在重新解释您的要求时冒昧,因此这里有一些假设您必须确认才能有效。

我假设您正在寻找每人至少一组 2 部电影,这些电影在 30 天内发布(否则您不会期望 Bob 的条目出现在您的搜索结果中)。

我还假设您打算让电影 X 的 publish_date 为 2016-03-09 而不是 2018-03-09,否则它不应该出现在预期结果中。

有了这些假设,这个查询应该可以解决问题:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WITH p, m 
ORDER BY m.publish_date
WITH p, collect(m) as movies, collect(m.publish_date) as dates
UNWIND range(0, size(movies)-2) as index
WITH p, movies, dates, index 
WHERE duration.inDays(dates[index], dates[index+1]).days <= 30
UNWIND [movies[index], movies[index+1]] as movieInRange
RETURN DISTINCT p, movieInRange
ORDER BY p.name DESC

我们 UNWIND 比每个人的电影列表大小小 0 到 2 的范围,以便我们可以对列表进行索引(我们将成对评估电影日期,以便进行比较)。

对于在 30 天内发布的相邻对,我们 UNWIND 相邻电影的集合,使电影都在同一个变量下,然后我们返回排序后的 DISTINCT 值(因为同一部电影可能会出现两次,在电影前后的 30 天内。

【讨论】:

    【解决方案2】:

    此查询将告诉您同一个人的任何两部电影是否相隔不到 30 天。从那里您可以根据需要进行过滤:

    MATCH (m1:Movie)<-[:ACTED_IN]-(p:Person)-[:ACTED_IN]->(m2:Movie) 
    WITH p, m1,m2, datetime(m1.Publish_Date) as date1, datetime(m2.Publish_Date) as date2
    return p.name,m1.title,m2.title,
    CASE WHEN date1<date2
    THEN date1+duration("P30D")>date2
    ELSE date2+duration("P30D")>date1 END AS lessThan30DaysApart
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      • 2016-11-15
      相关资源
      最近更新 更多