有没有办法在 tinkerpop 中链接遍历? 除了 .flatMap()

问题描述

我们有一个照片共享应用程序,我正在使用 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();