我得到了一个图,其中每个节点都有标签a或B,每个标签的id属性上都有一个索引:
CREATE INDEX ON :A(id);
CREATE INDEX ON :B(id);
在这个图中,我想找到id为"42"的节点,但我事先不知道标签。为此,我正在执行以下查询:
MATCH (n {id:"42"}) WHERE (n:A OR n:B) RETURN n;
但是这个查询需要6秒钟才能完成。但是,执行以下任一操作:
MATCH (n:A {id:"42"}) RETURN n;
MATCH (n:B {id:"42"}) RETURN n;
仅需约10ms。
我的问题表述不正确吗?制定该指数的正确方法是什么,以便利用已安装的指数?
这里有一种使用这两个索引的方法。result
将是匹配节点的集合。
OPTIONAL MATCH (a:B {id:"42"})
OPTIONAL MATCH (b:A {id:"42"})
RETURN
(CASE WHEN a IS NULL THEN [] ELSE [a] END) +
(CASE WHEN b IS NULL THEN [] ELSE [b] END)
AS result;
您应该使用PROFILE来验证neo4j环境的执行计划是否对两个OPTIONAL MATCH
子句都使用了NodeIndexSeek操作。如果没有,可以使用USING INDEX子句向Cypher提供提示。
您应该使用UNION来确保使用这两个索引。在你的问题中,你几乎得到了答案。
MATCH (n:A {id:"42"}) RETURN n
UNION
MATCH (n:B {id:"42"}) RETURN n
;
这会奏效的。若要检查查询,请在查询语句之前使用配置文件或解释来检查是否使用了索引。
索引是通过节点标签和属性形成和使用的,要使用它们,您需要以相同的方式形成查询。这意味着没有标签的查询将扫描所有节点并得到结果。