有没有一种方法可以将多个WHERE语句链接在一起而不切换到Neo4j和Neo4j中?
我有一个使用Neo4j数据库的大型应用程序。有几十种方法可以保存密码查询。为了删除每个方法存储自己的完整查询时可能存在的重复代码,我创建了私有方法,用于构建查询中常用的小块。例如,以下方法:有没有一种方法可以将多个WHERE语句链接在一起而不切换到Neo4j和Neo4j中?,neo4j,cypher,Neo4j,Cypher,我有一个使用Neo4j数据库的大型应用程序。有几十种方法可以保存密码查询。为了删除每个方法存储自己的完整查询时可能存在的重复代码,我创建了私有方法,用于构建查询中常用的小块。例如,以下方法: MatchNodesWithLabel(string label) 将返回类似以下内容的部分查询: MATCH (node:label) 这些方法调用之后是添加WHERE或RETURN语句以构建完整查询的方法。这是一个小例子,有一些方法可以匹配和过滤整组节点和关系 当需要将多个其中的语句链接在一起时,就
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
语句中的索引!这使得这些查询对于大型数据集的性能慢得令人无法接受。我强烈建议不要使用这种技巧,而是牺牲一些代码可读性或代码复制来获得良好的性能。您的代码可以有两个集合:saymatches
和where
。MatchX()和WhereY()方法可以将适当的数据附加到各自的集合中。准备提交查询时,可以从这些集合中的数据生成MATCH
和WHERE
子句