我有一个图表,其中每个节点都有标签A或B,以及每个标签的id属性索引:
CREATE INDEX ON :A(id);
CREATE INDEX ON :B(id);
在此图中,我想找到ID为#34; 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;
仅需约10毫秒。
我没有正确制定我的查询吗?制定它的正确方法是什么,以便利用已安装的指数?
答案 0 :(得分:2)
这是使用两个索引的一种方法。 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提供提示。
答案 1 :(得分:2)
您应该使用UNION来确保使用这两个索引。在你的问题中,你几乎得到了答案。
MATCH (n:A {id:"42"}) RETURN n
UNION
MATCH (n:B {id:"42"}) RETURN n
;
这会奏效。检查查询使用配置文件或在查询语句之前解释以检查是否使用了索引。
答案 2 :(得分:1)
索引是通过节点标签和属性形成和使用的,要使用它们,您需要以相同的方式形成查询。这意味着没有标签的查询将使用您获得的结果扫描所有节点。