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

Is there a way to chain traversals in tinkerpop ? (other than .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(); 
    }

根据 userId,我们从其他系统检索正确的 direction/relation 信息,并将其用于结果。

不幸的是,当 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();