我正在尝试查找人和位置之间存在关系的节点,并在某个边界框中过滤该位置。
我能够产生我需要的结果,但性能不佳正在成为一个问题:
在下面的示例中,我从一个用户开始,查找用户或用户知道的任何人(最多 3 个关系深度)访问过的所有位置。
START
user = node:USER('username:"testuser"')
MATCH
user-[:KNOWS*0..3]->(users)<-[:VISITED]-place
RETURN
place;
性能很好(<200 ms)。
一旦我添加了空间过滤器,执行时间就会跳到 10 秒。
START
user = node:USER('username:"testuser"'),
place = node:LOCATION("bbox:[-0.32487837,0.10114981,50.469185,52.508842]")
MATCH
user-[:KNOWS*0..3]->(users)<-[:VISITED]-place
RETURN
place;
空间查询本身返回非常快(< 100 ms),只有当您将这两个开始条件放在一起时,查询才会刹车。
有没有更好的方法来构造这个查询,让它表现得更好?
对于使用空间过滤器和其他索引条件执行查询有什么建议吗?
附加上下文: 这是通过 Web 控制台的 Neo4j 1.9.2。在上面的示例中,来自 testuser 的 0-3 级用户数为 16。Universe 中的位置数大于 1000。边界框内的地点数为 933。结果中的最终地点数为 290。节点本身非常小 - 只有 ID 和空间数据。整个图形数据库大小约为 7 MB。
更新了查询计划
==> ColumnFilter(symKeys=["users", "user", " UNNAMED6", "place", " UNNAMED5"], returnItemNames=["place"], _rows=2633, _db_hits=0)
==> PatternMatch(g="(user)-[' UNNAMED5']-(users)", _rows=2633, _db_hits=0)
==> Nodes(name="user", _rows=13281, _db_hits=13281)
==> TraversalMatcher(trail="(place)-[ UNNAMED6:VISITED WHERE true AND true]->(users)", _rows=13281, _db_hits=14214)
==> ParameterPipe(_rows=1, _db_hits=0)
我重建了图表,调整了内存,关闭了所有其他正在运行的应用程序,将其移至更快的服务器并将其缩短到 2 秒。在生产场景中,数据将增长 2 位有效数字,因此这确实需要在 1/10 秒的空间内......