问题描述
我们有一个照片共享应用程序,我正在使用 tinkerpop 3.4.3 java 库和 AWS Neptune 图。在我们的应用程序中,我们已经使用 .flatMap() 步骤来链接来自其他方法的遍历。我们当前的代码是这样的。
public boolean isViewable(String photoId,String userId) {
return graph.V(photoId).hasLabel("photo")
.flatMap(getDirection(userId))
.otherV().hasId(userId).hasNext();
}
根据用户 ID,我们从其他系统中检索正确的方向/关系信息,并在此处使用它作为结果。
不幸的是,当 photoId 的边数很高(100K 边)时,我们在使用 .flatMap() 步骤时面临边缘性能问题。
...flatMap(inE()).otherV().profile() 结果约 5000 毫秒,但没有 .flatMap 的相同查询结果不到 200 毫秒。
public boolean isViewable(String photoId,String userId) {
GraphTraversal<Vertex,Vertex> traversal = graph.V(photoId).hasLabel("photo");
applyDirection(traversal,userId);
traversal.otherV().hasId(userId).hasNext();
}
private void applyDirection(GraphTraversal<Vertex,Vertex> traversal,String userId) {
if(condition) {
traversal.inE();
} else {
traversal.outE();
}
}
但是没有链接的代码看起来很复杂。是否有任何其他步骤可用于链接遍历?
解决方法
我认为没有链接的代码不会那么复杂或难以阅读。在动态构建遍历时采用这种方法是很常见的。如果您真的不喜欢它,您可以 build a DSL 进行自定义步骤来封装该逻辑:
graph.V(photoId).hasLabel("photo")
.eitherInOrOut(userId)
.otherV().hasId(userId).hasNext();
如果确定 Direction
的逻辑真的那么简单,您还可以使用鲜为人知的 to()
step:
graph.V(photoId).hasLabel("photo")
.toE(getDirection(userId))
.otherV().hasId(userId).hasNext();