我正在Neo4j中设计一个用户授权/数据保护方案的原型,但在查询时遇到了奇怪的问题。背景是这样的,当一个用户从a到b时,如果他们有正确的访问标识符,则可以到达b。因此,我们的边缘类型中包含访问标识符。我通过创建大量节点,并使用不同的访问权限将它们配对连接来测试此方案。也就是说,我有很多组:
(a)-[:ACCESS_A]->(b)
通过不同的访问权限。我使用以下方式查询它们:
{some query} with a match (a)-[:ACCESS_A|:ACCESS_B|<...>|:ACCESS_Z]->(b) return b
边缘匹配列表的大小随用户访问次数增加而增长。
这一切都很顺利,直到列表达到201个访问。此时,配置文件显示数据库命中次数和花费时间急剧增加。在200种关系类型下,配置文件显示1051个数据库命中,但201种关系类型下显示31801个命中。只为了多一个类型,就增加了30倍!时间的增加方式类似。从199到200仅仅增加了约50个命中,这是由于被访问节点数量的增加。
经过更多的工作,似乎200这个数字更多的是一个误导,而不是问题的根源。以前,我的关系类型有4个字符。当我将它们改为9个字符(作为测试,加入"EDGE_"前缀)时,问题开始在50个类型时发生——50个类型有36次访问,而51个类型有291次访问——虽然与同一测试中之前的增长相比要小,但仍然显着。
看起来关系名称与查询失效的位置有一定关系,但我还在调查中。
我已经测试过但未发现有趣的事情:
- 整个查询的长度(字符串大小):使用4个和9个字符的关系类型,在完全不同的查询大小上失败
- [e:<...>]子句中列表的长度(字符串大小):与上述一样,它在非常不同的大小上失败
- 图中节点或边缘的数量