我正在尝试弄清楚如何使用 Gremlin API 和 CosmosDb 在图形节点上添加或减去现有属性(数字类型)。
假设我想跟踪垃圾箱中小部件的库存数量:
g.addV('Bin').Property('id', '1').Property('Widgets', 100)
我可以轻松获取当前值:
g.V('1').Properties('Widgets').Value()
并更新值,比如说如果我从垃圾箱中取出一个小部件,我会做我的数学然后设置新值:
g.V('1').Property('Widgets', 99)
问题是在高并发的情况下可能会出现这种情况。应用程序获取当前值的竞争条件很有可能发生,然后在它可以更新为新值之前被另一个消费者更改。
目前,这些步骤彼此尽可能接近(实际上只是中间的数学步骤),但我现在正在寻找可能有几十个并发进程都在做这件事。
我想象这样的查询:
g.V('1').Properties('Widgets').Value().Store('x').V('1').Property('Widgets', Math('x - 1'))
但不幸的是,CosmosDB 不支持 math() 步骤。
这让我尝试传递遍历的结果,但我得到类型错误,CosmosDB 抱怨输入是遍历而不是值,即使(我认为?)它应该得到值。
例子:
g.V('1').Properties('Widgets').Value().Store('x').V('1').Property('Widgets', Select('x'))
返回此错误:
提交查询失败: g.V('1').Properties('Widgets').Value().Store('x').V('1').Property('Widgets', 选择('x')):脚本评估错误:ActivityId: 3438873e-2cca-4c65-a221-dc56c4468a5f 异常类型: GraphRuntimeException 异常消息:Gremlin 查询执行 错误:无法在非原始类型 GraphTraversal 上创建 ValueField。 GremlinRequestId:86242ae1-5e1e-4cf4-8cbc-a68fccf535b0 上下文: graphcompute 范围:graphstg-logplan GraphInterOpStatusCode: GraphRuntimeError HResult:0x80131500
我尝试了几个变体,这个返回相同的错误:
g.V('1').Properties('Widgets').Value().Store('x').V('1').Property('Widgets', Select('x').Value())
这个将“Widgets”的值设置为字面值“x”....
g.V('1').Properties('Widgets').Value().Store('x').V('1').Property('Widgets', 'x')
还有告诉查询我拿了多少小部件的问题,但如果第一个问题解决了,那么接下来就是。
我在想我可能会以这样的方式结束,其中设置了占位符属性并将求和函数输出作为新值传入。例如,这个遍历/s给出了正确的期望值:
g.V('1').Property('Diff', -1).V('1').Properties('Widgets', 'Diff').Value().Sum()
但是如果您尝试将其作为 Widgets 属性的新值传递,它会抛出与上述相同的类型错误(不接受遍历):
g.V('1').Property('Diff', -1).V('1').Properties('Widgets', 'Diff').Value().Sum().as('x').V('1').Property('Widgets', select('x'))