从下面提供的2种方法中,验证gremlin的节点和边缘的最佳方法是什么?

时间:2019-06-06 13:11:25

标签: java gremlin gremlin-server

我使用gremlin server(版本3.4.0)从我的Java应用程序连接到gremlin-driver(版本3.4.0)。我正在使用以下代码从Java连接到服务器。

Cluster cluster = Cluster.build("localhost").port(8182).create();
Client client = cluster.connect();
GraphTraversalSource graphTraversalSource = AnonymousTraversalSource.traversal()
    .withRemote(DriverRemoteConnection.using(client, "g"));

// To get the list of vertices
List<Vertex> vertices = graphTraversalSource.V().toList();

//To add a vertex
GraphTraversal newNode = graphTraversalSource.addV("Label 1");

//To add properties to the vertex
newNode.property("key1","value1");
newNode.property("key2",1002);

现在,我要求每个顶点必须具有一些预定义但动态的属性,例如名称,uuid等。这些预定义的属性可能因顶点而异(基于顶点标签),并且将来可能会更改;因此是动态的。由于这种动态,我无法使用预定义的gremlin模式。

现在,我认为我有两种实施方式。

Approach 1.我可以将验证逻辑保留在我的Java应用程序上,并且仅在有效时才传递给gremlin。

Approach 2.我可以实现一些遍历策略,例如EventStrategy

第一个选择是直接前进,那里没有火箭科学。对于第二种选择,我面临以下问题。

Issue 1.在使用相同的GraphTraversalSource实现remotestrategy的地方找不到任何引用。

Issue 2.如果验证失败,如何停止创建顶点。

我尝试了以下操作,以使用相同的GraphTraversalSource来实现remotestrategy,但它给了我序列化错误。

// Here GremlinMutationListener is a class which implements MutationListener

MutationListener mutationListener = new GremlinMutationListener();
EventStrategy eventStrategy = EventStrategy.build().addListener(mutationListener).create();
GraphTraversalSource graphTraversalSource = AnonymousTraversalSource.traversal()
    .withRemote(DriverRemoteConnection.using(client, "g"))
    .withStrategies(eventStrategy);

我得到的错误是

Caused by: java.lang.IllegalArgumentException: Class is not registered: org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategy
Note: To register this class use: kryo.register(org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategy.class);

MutationListener中,除了抛出异常外,我没有找到一种方法来停止执行并返回验证错误。可能会有很多开销

public class GremlinMutationListener implements MutationListener {
    private static final Logger LOGGER =
            LoggerFactory.getLogger(GremlinMutationListener.class);

    @Override
    public void vertexAdded(Vertex vertex) {
        LOGGER.info("SS: vertexAdded " + StringFactory.vertexString(vertex));
        // How can I return the validation error from here besides throwing exception?
        // Is there some other interface which I should implement?
    }

    .
    .
    .
    .

现在的问题是,考虑到性能,这里1或2的最佳方法是什么。如果是2,如何解决我面临的问题(1和2)。

1 个答案:

答案 0 :(得分:0)

EventStrategy并不是进行验证的好方法。直到在基础图形中发生更改后,您才会收到事件通知,因此验证错误为时已晚。

我确实认为TraversalStrategy是实现验证的一种简洁方法。我认为您会:

  1. 实施自己的ValidationTraversalStrategy以查找任何突变步骤,然后检查它们的内容是否包含“错误数据”,如果有问题,则引发异常。由于策略应用发生在遍历迭代之前,因此您将在遍历遍历底层图形之前停止遍历。
  2. 在Gremlin Server中配置“ g”以使用具有策略设置服务器端,以便与它的所有连接都自动受益于该策略。

这里的缺点是,并非所有图形都支持包含自定义遍历策略的功能,因此,您需要通过采用这种方法来减少代码的可移植性。

另一种更可移植(也许更容易)的方法是构建Gremlin DSL。这样,您可以在构造遍历时立即实现验证客户端。例如,您可以添加以下步骤:

public default GraphTraversal<S, Vertex> person(String personId, String name) {
    if (null == personId || personId.isEmpty()) throw new IllegalArgumentException("The personId must not be null or empty");
    if (null == name || name.isEmpty()) throw new IllegalArgumentException("The name of the person must not be null or empty");

    return coalesce(__.V().has(VERTEX_PERSON, KEY_PERSON_ID, personId),
                    __.addV(VERTEX_PERSON).property(KEY_PERSON_ID, personId)).
            property(KEY_NAME, name);
}

该示例摘自KillrVideo example repo-您可以在此处查找更多灵感,还可以考虑与该回购相关的相关博客文章:

  1. https://www.datastax.com/dev/blog/gremlin-dsls-in-java-with-dse-graph
  2. https://academy.datastax.com/content/gremlin-dsls-python-dse-graph
  3. https://academy.datastax.com/content/gremlin-dsls-net-dse-graph

即使这些博客帖子使用不同的编程语言,每个帖子的内容也适用于使用任何语言使用Gremlin的任何人。