Cypher查询优化 - 利用节点的已知属性

时间:2015-04-11 15:43:52

标签: neo4j cypher

设定:

Neo4j和Cypher 2.2.0版。 我在Eclipse中查询Neo4j作为内存实例创建了TestGraphDatabaseFactory()。newImpermanentDatabase();. 我使用这种方法似乎比嵌入式版本更快,我认为它具有相同的功能。 我的图数据库是以编程方式随机生成的,具有不同数量的节点。

背景:

我自动生成密码查询。这些查询用于尝试识别单个目标'节点。我可以使用已知的“节点”来限制查询的可能匹配。属性。我只使用'名称'在这种情况下的财产。如果节点有已知名称,我可以使用它来查找节点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

另一种思考这个问题的方法(如果它有帮助)是,这是一个同构测试问题,我们有一些关于查询和目标图中的节点如何根据标签限制相互对应的信息。

问题:

关于优化:

  1. 在match子句中包含关系变量会有帮助吗?我拿出它们是因为节点变量足以区分关系,但这可能会减慢它的速度?
  2. 我是否应该重新配置匹配条款以匹配/包括前一个例子中where子句的夫妇?我的期望是他们可以在早期限制可能的绑定。例如......

    START

    nvari = node(5)

    MATCH

    (nvarj:C2) - [:IN_LOCATION] - >(nvarg:LOCATION)

    哪里没有(nvarj.Name IN [' nf'])

    MATCH

    (nvarm:C3) - [:IN_LOCATION] - >(nvarg:LOCATION)

    WHERE NOT(nvarm.Name IN [' nb',' nj'])

    MATCH

    (目标:C5) - [:IN_LOCATION] - GT;(nvara:LOCATION), (nvara:LOCATION) - [:CONNECTED] - GT;(nvarb:LOCATION), (nvara:LOCATION) - [:CONNECTED] - GT;(nvarc:LOCATION), (nvard:LOCATION) - [:CONNECTED] - GT;(nvarc:LOCATION), (nvard:LOCATION) - [:CONNECTED] - GT;(nvare:LOCATION), (nvare:LOCATION) - [:CONNECTED] - GT;(nvarf:LOCATION), (nvarg:LOCATION) - [:CONNECTED] - GT;(nvarf:LOCATION), (nvarg:LOCATION) - [:CONNECTED] - GT;(nvarh:LOCATION), (nvare:LOCATION) - [:CONNECTED] - GT;(nvark:LOCATION)

    RETURN DISTINCT目标

  3. 旁边:

    1. (不太重要但仍然感兴趣)如果我在匹配子句中使每个关系成为可选匹配(包含目标节点的关系除外),那么密码本质上就是查找查询和图数据库之间的最大公共子图具有MCS包含目标节点的约束?
    2. 提前多多感谢!我希望我的要求清楚,但我很欣赏这不是Neo4j的典型用例。

1 个答案:

答案 0 :(得分:1)

  1. 我认为查询节点属性几乎总是比使用关系属性更好(如果你有选择),因为这开启了索引可以帮助加速查询的可能性。

    顺便说一句,如果可能值的集合只有一个元素,我会避免使用IN运算符。例如,此代码段NOT(nvarj.Name IN ['nf'])应为(nvarj.Name <> 'nf')。当前版本的Cypher可能不会使用IN运算符的索引。

  2. 重新构建查询以消除不必要的绑定,这正是应该正在做的事情。

  3. 首先,您需要继续使用MATCH至少查询中的第一个关系(绑定target),否则您的结果将包含大量{ {1}}行 - 不太有用。

    但是,要清楚地思考这个问题,如果所有其他关系都放在单独的null条款中,那么即使 none 可选,你基本上也要说你想要匹配比赛成功了。因此,逻辑等价物将是:

    OPTIONAl MATCH

    我认为这不是一个有用的结果。