Neo4j Cypher查询未按预期工作

时间:2018-04-10 13:45:33

标签: neo4j cypher

我需要一些帮助。我有graph。它适用于项目管理应用程序

Day节点表示为follows。 Occupancy节点具有START和Day节点的可选END关系,Employee节点与Occupancy节点具有OCCUPIES关系。 Occupancy节点与Project节点具有OCCUPIES关系。

所以我的问题是:让所有在特定日期占用项目的员工。

到目前为止我的查询:

match (employee:Employee)-[:OCCUPIES]->(o:Occupancy)-[:OCCUPIES]->(project:Project{uuid:"ed409308-3202-495f-b834-ef1e8d5039d6"})
with employee, o
match(:Year{value:2018})-[:CONTAINS]->(:Month {value:10})-[:CONTAINS]->(day:Day {value:10})
with day, employee, o
match(o)-[:START]-(start:Day)-[:NEXT*0..365]->(day)
optional match(o)-[:END]-(end:Day)
optional match(day)-[:NEXT*0..300]->(end)
return employee

但这不起作用。无论他们的入住率是否在日期之前结束,它都会给我所有员工。上图中的示例所有占用率从10.april.2018开始,其中一半在1.june.2018结束。在查询中我得到了日期10.october.2018。

有人可以帮我吗?

关于斯拉夫科

3 个答案:

答案 0 :(得分:0)

您可以尝试此查询:

MATCH 
     (:Year{value:2018})-[:CONTAINS]->(:Month {value:10})-[:CONTAINS]->(day:Day {value:10}),
    (employee:Employee)-[:OCCUPIES]->(o:Occupancy),
    (o)-[:OCCUPIES]->(project:Project{uuid:"ed409308-3202-495f-b834-ef1e8d5039d6"}),
    (o)-[:START]->(start:Day),
    p=shortestpath((start)-[:NEXT*]->(day))
WHERE all(day IN NODES(p) WHERE NOT (o)-[:END]->(day))
RETURN employee

这里的技巧是我搜索开始日和查询日之间的最短路径。对于此路径中的每个节点,我都会检查与END没有Occupation的关系。

通常情况下,您应该只搜索Occupation个节点。

答案 1 :(得分:0)

  1. 以下子句匹配开始所需的所有占用所需的开始日期(包括所需的开始日期)。这可能是所有员工都被退回的原因。

    MATCH (o)-[:START]-(start:Day)-[:NEXT*0..365]->(day)
    

    如果您想查找以特定day开头的占用情况,您应该使用此功能:

    MATCH (o)-[:START]-(day)
    

    或者,如果你真的想在那个日期之后找到在特定day或一年之后开始的占用,你应该使用以下内容(我会假设这是什么你想要的):

    MATCH (o)-[:START]-(start:Day)<-[:NEXT*0..365]-(day)
    
  2. 您的OPTIONAL MATCH条款目前对是否返回employee完全没有影响。 (此外,这些条款仅匹配开始后300天内的end个日期day - 我将假设这是您的用例的要求,即使您的问题中未说明。)

  3. 以下查询尝试解决这两个问题,并且可能对您有用:

    MATCH (employee:Employee)-[:OCCUPIES]->(o:Occupancy)-[:OCCUPIES]->(project:Project{uuid:"ed409308-3202-495f-b834-ef1e8d5039d6"})
    MATCH (:Year{value:2018})-[:CONTAINS]->(:Month {value:10})-[:CONTAINS]->(day:Day {value:10})
    MATCH (o)-[:START]-(start:Day)<-[:NEXT*0..365]-(day)
    OPTIONAL MATCH (o)-[:END]-(end:Day)
    OPTIONAL MATCH p=(day)-[:NEXT*0..300]->(end)
    RETURN CASE WHEN p IS NULL THEN employee ELSE NULL END AS employee;
    

    注意:每个候选员工所需的所有NEXT关系跃点,以满足此查询(最多665)似乎很昂贵。您可能想要提供更有效的数据模型(但如果您需要帮助,则需要一个新问题)。

答案 2 :(得分:0)

感谢您的回答。它帮我分配了。我根据你的帮助写的查询:

match(:Year{value:{y}})-[:CONTAINS]->(:Month {value:{m}})-[:CONTAINS]->(day:Day {value:{d}})
            with day
            match (employee:Employee)-[:OCCUPIES]->(o:Occupancy)-[:OCCUPIES]->(project:Project{uuid:{project}})
            with day, employee, project, o
            match (o)-[:START]->(start:Day)
            with day, employee, project, o, start
            match p=shortestpath((start)-[:NEXT*0..365]->(day))
            with day, employee, project, o, start, p
            WHERE all(day IN NODES(p) WHERE NOT (o)-[:END]->(day))
            optional match(employee)-[:WORKS]->(dayshift:Shift{shifttype:0})-[:WORKDAY]->(day)  
            optional  match(dayshift)-[:WORKS]->(project)
            optional match(employee)-[:WORKS]->(nightshift:Shift{shifttype:1})-[:WORKDAY]->(day)  
            optional  match(nightshift)-[:WORKS]->(project)            
            return employee, dayshift, nightshift

但我还有一个问题。如果占用开始时让我们说1.april.2018并结束1.april.2018所以它是一天。对于这种情况,上面的查询不起作用,因为它具有END关系。

有任何建议如何解决?