有很多方法可以做到这一点,但我认为 TinkerPop 社区普遍采用这种方法:
g.V().has('event','id','1').
fold().
coalesce(unfold(),
addV('event').property('id','1'))
基本上,它使用has() 查找“事件”并使用fold() 步骤强制到一个列表。该列表要么为空,要么包含Vertex。然后使用coalesce(),它会尝试unfold() 列表,如果它有一个Vertex,否则会立即返回,它会执行addV()。
如果想法是在找到元素后更新现有属性,只需在coalesce() 之后添加property() 步骤:
g.V().has('event','id','1').
fold().
coalesce(unfold(),
addV('event').property('id','1')).
property('description','This is an event')
如果您需要知道返回的顶点是否是“新的”,那么您可以执行以下操作:
g.V().has('event','id','1').
fold().
coalesce(unfold().
project('vertex','exists').
by(identity()).
by(constant(true)),
addV('event').property('id','1').
project('vertex','exists').
by(identity()).
by(constant(false)))
关于这个主题的更多阅读可以在这个问题上找到:“Why do you need to fold/unfold using coalesce for a conditional insert?”
另请注意,此处描述了可选的边缘插入:“Add edge if not exist using gremlin”。
最后一点,虽然这个问题是关于 CosmosDB 的,但答案通常适用于所有启用 TinkerPop 的图。当然,图如何优化这个 Gremlin 是一个单独的问题。如果图具有原生 upsert 功能,则该功能可能会或可能不会在此 Gremlin 的幕后使用,因此可能有更好的方法通过图系统原生 API 实现 upsert(当然,选择该路径会降低你的代码)。