我有一个用户名数组(例如['abc','def','ghi']
),需要将它们添加到图表的“user”标签下。
现在,我首先要检查用户名是否已经存在(g.V().hasLabel('user').has('username','def')
),然后只添加那些用户名属性不匹配的用户到“user”标签下。
另外,这可以通过单个Gremlin查询或Groovy脚本完成吗?
我正在使用Titan图形数据库、TinkerPop3和Gremlin REST服务器。
我有一个用户名数组(例如['abc','def','ghi']
),需要将它们添加到图表的“user”标签下。
现在,我首先要检查用户名是否已经存在(g.V().hasLabel('user').has('username','def')
),然后只添加那些用户名属性不匹配的用户到“user”标签下。
另外,这可以通过单个Gremlin查询或Groovy脚本完成吗?
我正在使用Titan图形数据库、TinkerPop3和Gremlin REST服务器。
使用“脚本”,您可以始终将多行/命令脚本传递到服务器进行处理,以完成您想要的操作。然后,可以使用常规编程技术(如变量、if / then语句等)来回答这个问题:
t = g.V().has('person','name','bill')
t.hasNext() ? t.next() : g.addV('person').property('name','bill').next()
或者说:
g.V().has('person','name','bill').tryNext().orElseGet{
g.addV('person').property('name','bill').next()}
但是这些都是Groovy脚本,TinkerPop最终建议避免使用脚本和闭包,而是使用纯遍历。处理单个遍历中的“获取或创建”的一般方法是执行以下操作:
gremlin> g.V().has('person','name','bill').fold().
......1> coalesce(unfold(),
......2> addV('person').property('name','bill'))
==>v[18]
另请参阅此 StackOverflow问题,了解有关upsert /“获取或创建”模式的更多信息。
更新:从TinkerPop 3.6.0开始,fold()/ coalesce()/ unfold()
模式已经在很大程度上被新步骤所取代的 mergeV()
和mergeE()
。这极大地简化了执行类似upsert操作所需的Gremlin。在3.6.0及更高版本下,您应编写以下内容:
g.mergeV([(label): 'person', name: 'bill'])
来完成。
g.V().has('user','username','def').fold().coalesce(unfold(),addV('user').property('username','def'))
在这个答案中补充一点。最好使用以下幂等查询。Coalesce的工作原理类似于if-else语句。有关更多信息,请参见https://spin.atomicobject.com/2021/08/10/idempotent-queries-in-gremlin/。此外,如果您注意到条目未被保存,请确保使用.next()
提交更改。
g.V().hasLabel('user').has('username','def')
.fold()
.coalesce(
__.unfold(),
__.addV('user').property('username','def')
)
.next()
fold()
/unfold()
。 - Gyromite