我正在使用spring-data-neo4j
通过 REST api 访问独立的 Neo4J 服务器。在通过 spring 存储库检索对象时观察到严重的性能问题,@MapResult
用于转换检索到的对象列表。
首先,我在服务器日志 ( http.log ) 中观察到,当我们开始在检索到的@MapResult
接口上迭代或调用 getter/setter 时,会在后台触发大量 REST 请求。在一种情况下,当 Neo4J 服务器在同一台机器上运行时,它在迭代和访问 5 个@MapResult
对象的列表时触发了 1900 多个休息请求,耗时超过 6 秒。
我将问题简化为获取一个简单的关系,如下所示。我可以在 Neo4J 服务器日志中看到,当我调用MyMapResultInterface.getRoute()时,会触发 9 个 http 请求来获取这个单个对象。这些http请求的数量是预期/设计的吗?还是我错过了什么?我可以找到非常少的关于用法@MapResult
及其含义的文档。
关系模型:
@RelationshipEntity(type="ROUTE")
@TypeAlias("Route")
public class Route {
@GraphId
private Long id;
@StartNode
private Location startAt;
@EndNode
private Location endAt;
private String routeName;
private String city;
private long distance;
private Date createdOn;
}
当我调用MyMapResultInterface.getRoute()时在http.log中看到的日志:
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/node/13/properties HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/node/25/properties HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
上面可以看到许多重复的GET 。只是一种解释,看起来GET的数量等于对象Route/db/data/relationship/28
中的字段总数,并且可能有两个GET请求可能针对and字段。/db/data/node/{nodeId}/properties
@StartNode
@EndNode
编辑:
根据我的观察,我注意到这不仅是问题,@MapResult
而且是来自存储库方法的简单映射结果的问题,示例如下
Iterable<Route> routes = routeRepository.getAvailableRoutesForUser(user.getId());
即便如此,也会向 neo4j 服务器发出大量 http rest 请求。
更新:
正如 Michael Hunger 在回答中所建议的那样,这两种方法可以提高 Neo4j REST api 的性能。然而,这会导致非常大的复杂密码查询和难以管理且难以维护的代码。
因此,最终在评估了所有方法之后,我们决定取消 Neo4j REST 接口并开始使用 Neo4j 嵌入式。并且嵌入的 Neo4j 不适用于 Heroku,我们不得不取消 Heroku。我们将应用程序迁移到 Amazon AWS。
我们希望 Neo4j 早日拿出生产环境中性能可以接受的远程访问通道。