繁体   English   中英

如何在 Amazon Neptune 中使用 Gremlin 有条件地添加顶点和多条边?

[英]How can I conditionally add a vertex and multiple edges using Gremlin in Amazon Neptune?

我将 Amazon Neptune 用于个人项目,但在编写查询时遇到了问题。 我正在使用 Gremlin-Java 来查询和改变图形。

我能想到的表示不同输入所需输出的最好方法是用图表,所以下面是图表形式的问题陈述,分为 3 种情况。 最后,不需要完整的解决方案(尽管会被接受)——即使是朝着正确的方向轻推也将不胜感激!

这是我应该执行此突变的代码,但它必须有一个缺陷(或多个缺陷!),因为它在案例 1中根本没有改变图形,因此我无法测试案例 2 案例 3案例 4案例 5也不会使用此代码表现出所需的行为。

void createShard(String username, String shardName, Set<String> inheritedShardNames, Set<String> inheritedUsers) {}
    g.V()
        .hasLabel("shard)
        .has("shardName", P.within(inheritedShardNames))
        .as("inheritedShards")
    .V()
        .hasLabel("user")
        .has("username", P.within(inheritedUsers))
        .as("inheritedUsers")
    .V()
        .has("user", "username", username)
        .as("user")
    .addV("shard)
        .property(single, "shardName", shardName)
        .property(single, "createdAt", new Date())
        .as("newShard")
    .addE("shardInheritsShard").from("newShard").to("inheritedShards")
    .addE("shardInheritsUser").from("newShard").to("inheritedUsers")
    .addE("userOwnsShard").from("user").to("newShard")
    .addE("userFollowsShard").from("user").to("newShard")
    .iterate();
}

情况1

Function 致电:

createShard(
    "john",
    "newShard",
    new HashSet<>(),
    new HashSet<>()
)

初始图 State UML

所需的最终图表 State UML

案例二

Function 致电:

createShard(
    "john",
    "newShard",
    new HashSet<>(Arrays.asList("firstShardToInherit", "secondShardToInherit")),
    new HashSet<>(Arrays.asList("john", "userToInherit"))
)

初始图 State UML

所需的最终图表 State UML

案例3

Function 致电:

createShard(
    "john",
    "newShard",
    new HashSet<>(Arrays.asList("userWhoDoesNotExist")),
    new HashSet<>(),
)

初始图 State UML

所需的最终图 State:与初始图 state 相同。 如果突变查询会抛出像java.util.NoSuchElementException这样的异常,或者给出一些其他指示图形没有被查询突变的指示,那将是理想的。

案例4

Function 致电:

createShard(
    "john",
    "newShard",
    new HashSet<>(Arrays.asList()),
    new HashSet<>(Arrays.asList("shardWhichDoesNotExist"))
)

初始图 State UML

所需的最终图 State:与初始图 state 相同。 如果突变查询会抛出像java.util.NoSuchElementException这样的异常,或者给出一些其他指示图形没有被查询突变的指示,那将是理想的。

案例5

Function 致电:

createShard(
    "john",
    "existingShardName",
    new HashSet<>(),
    new HashSet<>()
)

初始图 State UML

所需的最终图 State:与初始图 state 相同。 如果突变查询会抛出异常或给出其他指示图没有被查询突变,那将是理想的,因为已经存在具有相同 label 和“shardName”属性的顶点。

这是一个复杂的问题,但我认为您的问题往往源于假设您的遍历将比实际执行的更多。 让我们以“案例 1”为例,它从仅存在一个“用户”顶点开始,“名称”为“约翰”。 您的遍历开始于:

g.V().hasLabel("shard).
  has("shardName", P.within(inheritedShardNames)).as("inheritedShards")

由于图中现在有“分片”顶点,因此遍历立即不产生遍历器(即在 stream 中移动以携带数据的对象)并立即终止,因为没有任何东西可以触发下游步骤。 您似乎想要某种形式的 upsert 或“获取或创建”模式来解决您的问题。

Gremlin Console 中的一个简单示例演示了该问题:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().hasLabel('country').addV('person')
gremlin> g.V().hasLabel('country').fold().addV('person')
==>v[13]

第一个gV().hasLabel('country').addV('person')什么都不做,因为图中没有“国家”顶点,因此永远不会触发addV() 另一方面,在此之后的遍历确实添加了一个顶点,因为调用fold()是一种归约操作,它将产生一个携带空List object 的遍历器,这反过来又可以addV()

Gremlin 的 upsert 样式遍历的模式在很多地方都有描述。 请参见:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM