[英]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();
}
Function 致電:
createShard(
"john",
"newShard",
new HashSet<>(),
new HashSet<>()
)
Function 致電:
createShard(
"john",
"newShard",
new HashSet<>(Arrays.asList("firstShardToInherit", "secondShardToInherit")),
new HashSet<>(Arrays.asList("john", "userToInherit"))
)
Function 致電:
createShard(
"john",
"newShard",
new HashSet<>(Arrays.asList("userWhoDoesNotExist")),
new HashSet<>(),
)
所需的最終圖 State:與初始圖 state 相同。 如果突變查詢會拋出像java.util.NoSuchElementException
這樣的異常,或者給出一些其他指示圖形沒有被查詢突變的指示,那將是理想的。
Function 致電:
createShard(
"john",
"newShard",
new HashSet<>(Arrays.asList()),
new HashSet<>(Arrays.asList("shardWhichDoesNotExist"))
)
所需的最終圖 State:與初始圖 state 相同。 如果突變查詢會拋出像java.util.NoSuchElementException
這樣的異常,或者給出一些其他指示圖形沒有被查詢突變的指示,那將是理想的。
Function 致電:
createShard(
"john",
"existingShardName",
new HashSet<>(),
new HashSet<>()
)
所需的最終圖 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.