簡體   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