设置:
Neo4j和Cypher版本2.2.0。我正在查询Neo4j,因为Eclipse中的内存实例创建了TestGraphDatabase aseFactory(). newIm人永久数据库();。我使用这种方法,因为它看起来比嵌入式版本快,我假设它具有相同的功能。我的图形数据库是随机生成的,具有不同数量的节点。
背景:
我自动生成密码查询。这些查询用于尝试和识别单个“目标”节点。我可以通过使用已知的“节点”属性来限制查询的可能匹配。在这种情况下,我只使用“名称”属性。如果有一个节点的已知名称,我可以用它来查找节点id并在start子句中使用它。除了已知名称,我还知道(对于某些节点)是否有已知不属于节点的名称。我在where子句中指定了这一点。
我运行的各种查询看起来像这样…
START
nvari = node(5)
MATCH
(target:C5)-[:IN_LOCATION]->(nvara:LOCATION),
(nvara:LOCATION)-[:CONNECTED]->(nvarb:LOCATION),
(nvara:LOCATION)-[:CONNECTED]->(nvarc:LOCATION),
(nvard:LOCATION)-[:CONNECTED]->(nvarc:LOCATION),
(nvard:LOCATION)-[:CONNECTED]->(nvare:LOCATION),
(nvare:LOCATION)-[:CONNECTED]->(nvarf:LOCATION),
(nvarg:LOCATION)-[:CONNECTED]->(nvarf:LOCATION),
(nvarg:LOCATION)-[:CONNECTED]->(nvarh:LOCATION),
(nvari:C4)-[:IN_LOCATION]->(nvarg:LOCATION),
(nvarj:C2)-[:IN_LOCATION]->(nvarg:LOCATION),
(nvare:LOCATION)-[:CONNECTED]->(nvark:LOCATION),
(nvarm:C3)-[:IN_LOCATION]->(nvarg:LOCATION),
WHERE
NOT(nvarj.Name IN ['nf']) AND NOT(nvarm.Name IN ['nb','nj'])
RETURN DISTINCT target
另一种思考方式(如果有帮助的话)是,这是一个同构测试问题,其中我们有一些关于查询和目标图中的节点如何根据标签限制相互对应的信息。
问题:
关于优化:
>
我应该重构match子句以首先包含我之前示例中的where子句的match/where对吗?我的期望是它们可以尽早限制可能的绑定。例如…
开始
节点(5)
匹配
(n var j: C 2)-[:IN_LOCATION]-
不在哪里(nvarj.NameIN['nf'])
匹配
(nv arm: C 3)-[:IN_LOCATION]-
WHERE Not(nvarm.NameIN['nb','nj'])
匹配
(目标:C 5)-[:IN_LOCATION]-
返回DISTINCT目标
在侧面:
提前非常感谢!我希望我已经明确了我的要求,但我很感激这不是Neo4j的典型用例。
>
我认为使用节点属性进行查询几乎总是比使用关系属性更可取(如果您可以选择),因为这为索引有助于加快查询提供了可能性。
另外,如果可能值的集合只有一个元素,我会避免使用IN
运算符。例如,这个片段:NOT(nvarj.NameIN['nf'])
,应该是(nvarj.Name
重构查询以尽早消除不需要的绑定正是您应该做的事情。
首先,您需要至少对查询中的第一个关系(绑定target
)继续使用MATCH
,否则您的结果将包含大量null
行——不是很有用。
但是,考虑清楚这一点,如果所有其他关系都放在单独的OPTIONAl MATCH
子句中,你实际上是在说你想要一个匹配,即使没有一个可选匹配成功。因此,逻辑等价物将是:
MATCH (target:C5)-[:IN_LOCATION]->(nvara:LOCATION)
RETURN DISTINCT target
我认为这不是一个有用的结果。