有没有一种方法可以将多个WHERE语句链接在一起而不切换到Neo4j和Neo4j中?

有没有一种方法可以将多个WHERE语句链接在一起而不切换到Neo4j和Neo4j中?,neo4j,cypher,Neo4j,Cypher,我有一个使用Neo4j数据库的大型应用程序。有几十种方法可以保存密码查询。为了删除每个方法存储自己的完整查询时可能存在的重复代码,我创建了私有方法,用于构建查询中常用的小块。例如,以下方法: MatchNodesWithLabel(string label) 将返回类似以下内容的部分查询: MATCH (node:label) 这些方法调用之后是添加WHERE或RETURN语句以构建完整查询的方法。这是一个小例子,有一些方法可以匹配和过滤整组节点和关系 当需要将多个其中的语句链接在一起时,就

我有一个使用Neo4j数据库的大型应用程序。有几十种方法可以保存密码查询。为了删除每个方法存储自己的完整查询时可能存在的重复代码,我创建了私有方法,用于构建查询中常用的小块。例如,以下方法:

MatchNodesWithLabel(string label)
将返回类似以下内容的部分查询:

MATCH (node:label)
这些方法调用之后是添加
WHERE
RETURN
语句以构建完整查询的方法。这是一个小例子,有一些方法可以匹配和过滤整组节点和关系

当需要将多个
其中的
语句链接在一起时,就会出现问题。Cypher不允许
WHERE
语句跟随
WHERE
语句:

// Invalid
MATCH (node)
WHERE node:label
WHERE node.property = value
...
因此,任何超过第一个
的方法,其中
必须插入
语句:

// Valid
MATCH (node)
WHERE node:label
AND node.property = value
AND ...
这就产生了一个方法排序问题,其中某些方法不能在其他方法之后使用。插入
WHERE
语句的方法(
WHERE()
方法)必须位于
和()
Where()
方法不能在
和()
方法之后使用,而
和()
方法不能在
Where()
方法之前使用

以下是我为解决这个订购问题而提出的一些可能的(但最终失败的)解决方案:

  • 将每个
    Where()
    方法复制到一个等效的
    AndWhere()
    方法中,该方法执行相同的筛选,但使用
    而不是
    Where
    。然后在调用代码中,首先使用一个
    Where()
    方法,然后使用
    AndWhere()
    方法。
    • 这不是一个可接受的解决方案,因为代码重复,并且使调用代码复杂化。它只是将方法排序问题转移到调用代码,而不是解决问题。我希望能够随时添加
      Where()
      调用,而不必考虑我的方法是如何排序的
  • 在所有其他调用之前添加一个
    WHERE true
    语句,然后让每个
    WHERE()
    方法插入一个
    语句。
    • 这仅在调用代码中的方法是专门排序的情况下有效。所有
      MATCH
      方法都必须在
      WHERE true
      之前,否则您可能会得到一个类似于:
      
      匹配(节点)
      哪里是真的
      和节点:类型
      匹配(某物)
      还有somethingElse.property=value
      

      这是无效的,因为
      紧跟着一个
      匹配项
      ,而没有
      其中
      。因此,方法排序的责任再次转移到了调用代码上。使用此解决方案,每次启动一系列新的筛选调用时,都必须手动添加
      WHERE true
  • 分析现有查询,以确定在每个
    WHERE()
    方法的开始处是使用
    WHERE
    还是使用
    • 一开始这似乎没问题,您只需做一个类似于
      existingQuery.Contains(“WHERE”)
      的检查,如果为真,则插入
      。然而,这与#2有同样的问题。如果插入新的
      MATCH
      语句,检查仍将返回true,但查询不会处于
      为有效语句的状态。因此,您必须在查询中进一步分析,检查
      MATCH
      WHERE
      语句,并且必须跟踪它们出现的顺序,等等。。。这太复杂了

  • 是某种Neo4j语法,允许在任何地方插入
    WHERE
    ,还是一种我没有介绍过的查询构建解决方案?

    在每个
    WHERE
    语句之前添加一个带有*

    WITH*
    将把查询中已经存在的所有命名密码标识符带入一个新的查询中

    因此,查询结果如下所示:

    MATCH (node)
    WITH *
    WHERE ...
    WITH *
    WHERE ...
    MATCH (somethingElse)
    WITH *
    WHERE ...
    
    等等

    这允许在查询中的任何位置插入
    ,其中

    因此,每个
    Where()
    方法都将使用*Where
    插入
    ,而不仅仅是
    Where

    重要注意事项:这将减慢查询速度。每个带有
    都是投影,投影不是免费的。在我的测试中,使用带有*WHERE
    查询比等效的
    WHERE慢30%-50%。。。和
    查询

    这绝对是一个丑陋的解决方案。希望有一个更好的解决方案存在,一个与
    一样快的解决方案,其中。。。和
    query,并且不会使查询文本变得混乱,但是只要速度和查询可读性是可以接受的,这种解决方案就可以工作


    EDIT:我发现这个解决方案也会忽略
    WHERE
    语句中的索引!这使得这些查询对于大型数据集的性能慢得令人无法接受。我强烈建议不要使用这种技巧,而是牺牲一些代码可读性或代码复制来获得良好的性能。

    您的代码可以有两个集合:say
    matches
    where
    。MatchX()和WhereY()方法可以将适当的数据附加到各自的集合中。准备提交查询时,可以从这些集合中的数据生成
    MATCH
    WHERE
    子句