Neo4j:快速查询获取一组节点之间的关系

时间:2015-04-08 03:28:20

标签: performance neo4j cypher

我正在寻找一个快速的Cypher语句,它返回一组已知节点之间的所有关系(我有他们的Neo4j ID),这样我就可以组合该特定节点集的子图。我正在一个名为label的标签内工作,该标签在这些节点之间有大约50K节点和800K边缘。

我有几种工作方法,但是对于我的应用程序来说,没有一种方法足够快,即使在小的设置大小(少于1000个节点)时也是如此。

例如,以下语句可以解决问题:

MATCH (u:label)-[r]->(v:label)
WHERE (ID(u) IN {ids}) AND (ID(v) IN {ids}) 
RETURN collect(r)

其中{ids}是作为Py2Neo cypher.execute(statement, parameters)方法的参数给出的数字Neo4j ID的列表。问题是一组838个节点需要大约34秒,这会返回它们之间的所有19K关系。我意识到图形有点密集,但每返回1000条边需要1.76秒。我不认为这是可以接受的。

如果我改用START子句(如下所示),时间实际上会更糟糕。

START u=node({ids}), v=node({ids})
MATCH (u:label)-[r]->(v:label)
RETURN collect(r) 

我发现了很多类似的问题/答案,但在某些方面它们都不尽如人意。有没有更好的声明来做这个,甚至更好的图形模式,以便它可以扩展到数千个节点的集合?


更新

感谢您的快速回复。首先,要将当前查询作为输入(len(ids)=528)运行528个节点,需要 32.1秒,查询计划如下。

NodeByIdSeek: 528 hits
Filter      : 528 hits
Expand(All) : 73,773 hits
Filter      : 73,245 hits
Projection  : 0 hits
Filter      : 0 hits

Brian Underwood 的查询,输入相同, 27.8秒。查询计划是相同的,除了最后两个步骤(投影和过滤器),其查询不存在。然而db命中总和是相同的。

Michael Hunger 的查询 26.9秒,查询计划与Brian的查询相同。

我在实验之间重新启动服务器以避免缓存效果(这可能是一种更聪明的方法)。我也直接从网络界面查询,通过我的代码和我正在使用的库中可能存在的瓶颈。

Bottomline,Neo4j看起来很聪明,可以优化我的查询,但即使使用相当小的集合,它仍然很慢。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我认为问题在于查询正在使用笛卡尔积来获取838节点的所有组合,因此您最终搜索838 * 838 = 702,244个组合。

我很好奇这将如何表现:

MATCH (u:label)-[r]->(v:label)
WHERE (ID(u) IN {ids})
WITH r, v
WHERE (ID(v) IN {ids})
RETURN collect(r)

另外,为什么最后collect

答案 1 :(得分:0)

你的id列表有多大?

试试这个:

MATCH (u) WHERE ID(u) IN {ids}
WITH u
MATCH (v)-[r]->(v)
WHERE ID(v) IN {ids}
RETURN count(*)


MATCH (u) WHERE (ID(u) IN {ids})
WITH u
MATCH (v)-[r]->(v)
WHERE ID(v) IN {ids}
RETURN r

还可以尝试通过在PROFILE前面添加查询来创建查询计划,然后查看费用的位置。