【问题标题】:Is it possible to optimize the query in which nodes have an optional relationship?是否可以优化节点具有可选关系的查询?
【发布时间】:2017-11-14 07:59:06
【问题描述】:

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

尝试按应用程序和组织过滤节点(两个参数都是可选的),我创建了以下查询:

MATCH
(log0:Log)-[:GENERATED_IN]->(org:Organization),
(app:Application)<-[:GENERATED_IN]-(log1:Log)-[:GENERATED_IN]->(org:Organization)
WHERE ($orgID IS NULL
    OR ID(org)=$orgID)
AND ($appID IS NULL
    OR ID(app)=$appID)
RETURN DISTINCT
    CASE $appID
        WHEN null THEN log0
        ELSE log1
    END
    CASE $appID
    WHEN null then log1
    ELSE null
    END

我使用 2 个 CASE 表达式,因为 Cypher 仅返回与 :Organization 没有关系的节点为 log0(尽管我希望返回所有 :Log 节点)并且因为不可能返回几个来自CASE 的变量,i。 e.

RETURN DISTINCT
    CASE $appID
        WHEN null THEN log0, log1
        ELSE log1

这似乎不是一个可读性和可维护性很好的代码(特别是请记住,为了简单起见,我目前排除了许多其他过滤参数),那么是否有可能优化此查询?

【问题讨论】:

  • "esp. 请记住,为了简单起见,我目前排除了许多其他过滤参数" - 这些参数是用于过滤同一节点还是全部过滤不同的节点(类似于 appID, orgID 等)。
  • @GaborSzarnyas 其中一些过滤 :Log 属性(创建时间,重命名情况下的更改文本),其中一些过滤基于与其他节点的关系(@987654331 更改的作者@,用户对:Permission节点的权限)

标签: database optimization neo4j cypher


【解决方案1】:

您的查询可以返回包含 1 个或 2 个 Log 节点的映射,如下所示:

MATCH
  (log0:Log)-[:GENERATED_IN]->(org:Organization),
  (app:Application)<-[:GENERATED_IN]-(log1:Log)-[:GENERATED_IN]->(org)
WHERE ($orgID IS NULL OR ID(org)=$orgID)
  AND ($appID IS NULL OR ID(app)=$appID)
RETURN DISTINCT
  CASE $appID WHEN NULL
    THEN {a: log0, b: log1}
    ELSE {a: log1}
  END AS result;

【讨论】:

  • 在某些情况中,返回列表也可以,而且更短:CASE $appID WHEN NULL THEN [] ELSE [log0] END + [log1] AS result
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多