0

我有一个下面的简单查询,它创建一个新顶点并在同一查询中在旧顶点和新顶点之间添加一条边。此查询在大多数情况下都运行良好。当系统负载过重并且 RU 耗尽时,就会出现奇怪的行为。

g.V('2f9d5fe8-6270-4928-8164-2580ad61e57a').AddE('likes').to(g.AddV('fruit').property('id','1').property('name','apple'))

在低/正常负载下,上述查询创建水果顶点并在和之间1创建likes边。预期的行为。userfruit

在重负载下(可用的 RU 有限),上面的查询创建了fruit顶点,但没有在andlikes之间创建边。查询抛出状态码。如果我尝试重播查询,那么我会得到,因为顶点已经存在。此行为正在破坏数据。userfruit429409fruit

在很多地方我都有g.AddV查询。因此,所有这些查询都可能在重负载下中断。

如果我使用__.addV而不是有什么不同g.AddV吗?

更新:使用__.addV没有任何区别。

那么,我的查询错了吗?我需要在upsert任何需要添加边缘的地方做吗?

4

2 回答 2

1

我不知道 Microsoft 是如何实现 TinkerPop 的,因此我不确定以下内容是否有帮助,但您可以尝试先创建新顶点,然后在现有顶点中添加一条边。

g.addV('fruit').
    property('id','1').
    property('name','apple').
  addE('likes').
    from(V('2f9d5fe8-6270-4928-8164-2580ad61e57a'))

如果这也失败了,那么是的,一个 upsert 可能是你最好的选择,因为你可以无限期地重试相同的查询。但是,由于我对 CosmosDB 没有深入的了解,我无法判断它的 upserts 是否可以防止边缘重复。

于 2019-12-31T02:49:03.360 回答
0

在 Cosmos DB Gremlin API 中,事务范围仅限于对实体(顶点或边缘)的写入操作。因此,对于需要执行多个写入操作的 Gremlin 请求,可能会在失败时提交部分状态。

鉴于此,建议您使用幂等 gremlin 遍历,这样可以在出现 RequestRateTooLarge (429) 等错误时重试请求,而不会在重试时被冲突错误阻塞。

这是使用 step 重写的遍历coalesce(),因此它是幂等的(我假设 'name' 是分区键)。

g.V('1').has('name', 'apple').fold()
  coalesce(
    __.unfold(),
    __.addV('fruit').
       property('id','1').
       property('name','apple')).
 addE('likes').
    from(V('2f9d5fe8-6270-4928-8164-2580ad61e57a'))

注意:我没有将addE()a包装起来,coalesce()因为它是执行期间要执行的最后一个操作。如果在同一请求中的边缘之后会有额外的写入操作,或者如果您需要防止并发添加边缘请求的重复边缘,您可能需要考虑这样做。

于 2020-01-21T20:58:36.623 回答