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

What is the best approach from the 2 provided below to validate gremlin's node and edge?

我使用 gremlin-driver(版本 3.4.0)从我的 java 应用程序连接到 gremlin server(版本 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 除了抛出异常之外,我没有找到如何停止执行和 return 验证错误的方法;这可能会有很多开销

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)。

EventStrategy 不是进行验证的好方法。在底层图形中已经发生更改之前,您不会收到事件通知,因此验证错误来得太晚了。

我确实认为 TraversalStrategy 是实现验证的好方法。我认为你会:

  1. 实现您自己的 ValidationTraversalStrategy 以查找任何突变步骤,然后检查它们的内容 "bad data" 如果有问题则抛出异常。由于策略应用发生在遍历迭代之前,您将在它对基础图形进行修改之前停止遍历。
  2. 在 Gremlin 服务器中配置 "g" 以使用具有策略设置的服务器端,以便所有连接到它的自动获得该策略的好处。

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

另一种更便携(也许更容易)的方法是构建一个 Gremlin DSL。通过这种方式,您可以在构建遍历时立即实施验证 client-side。例如,您可以添加如下步骤:

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 - 您可以在那里寻找更多灵感,还可以考虑与该存储库相关的相关博客 post:

  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

尽管这些博客 post 使用不同的编程语言,但每个 post 的内容都适用于使用任何语言的 Gremlin 的任何人。