如何通过cypher中的可选关系参数进行过滤?

时间:2017-11-13 20:27:10

标签: database neo4j cypher

软件系统中有组织和应用程序。用户操作生成日志记录。日志记录(绿色)确实属于组织(红色),可能属于应用程序(粉红色)。

Neo4j DB model

需要通过各种参数(创建时间,作者,组织等)过滤日志记录。让我们所属的应用程序过滤日志记录,如果未指定此参数,则在系统中登记所有日志记录。为此,我创建了以下查询:

MATCH
(log0:Log)-[:GENERATED_IN]->(org:Organization),
(a1:Application)<-[:GENERATED_IN]-(log1:Log)
WHERE ID(a)=coalesce({applicationID}, ID(a))
RETURN DISTINCT
CASE {applicationID}
    WHEN null THEN log0
    ELSE log1
END
as result

因为参数是可选的,所以我需要处理未指定的情况。我决定在这种情况下使用ID(a)=coalesce({applicationID}, ID(a)),如果未指定ID(a)=ID(a)参数,则等于applicationID(因此我们只是不要通过此参数进行过滤,我真的要实现了。)

我想知道是否有更优雅的方式来通过可选关系进行过滤。我试过了

MATCH
(a:Application)<-[:GENERATED_IN*0..1]-(log:Log)-[:GENERATED_IN]->(org:Organization)
WHERE ID(a)=coalesce({applicationID}, ID(a))
RETURN 
log

还尝试了OPTIONAL MATCH的查询,但没有成功。我希望有待改进的建议。

顺便说一下,有没有办法从neo4j浏览器控制台指定{applicationID}等参数?像<query>, {applicationID}=202175一样。我每次都手动替换值。

1 个答案:

答案 0 :(得分:1)

您可以使用IS NULL代替coalesce,并检查参数是否已提供:

MATCH
  (log0:Log)-[:GENERATED_IN]->(org:Organization),
  (a1:Application)<-[:GENERATED_IN]-(log1:Log)
WHERE {applicationID} IS NULL
   OR ID(a1)={applicationID}
RETURN DISTINCT
  CASE {applicationID}
    WHEN null THEN log0
    ELSE log1
  END
  AS result

如果使用Neo4j 3.2+,我也会考虑切换到new parameter syntax$param而不是{param},这会使查询更容易阅读。