Azure cosmosdb 处理长整数类型时SQL SDK和存储过程之间的不一致
我们的团队使用Cosmos DB作为后端图形存储。基本上,由于gremlinapi的大小和步长限制,我们使用javagremlinsdk对顶点/边进行查询,并使用sqlsdk创建/更新顶点 我在尝试更新包含Long类型属性的顶点时遇到了这个问题。 在我们的代码中,我们使用Azure cosmosdb 处理长整数类型时SQL SDK和存储过程之间的不一致,azure-cosmosdb,azure-cosmosdb-sqlapi,azure-cosmosdb-gremlinapi,Azure Cosmosdb,Azure Cosmosdb Sqlapi,Azure Cosmosdb Gremlinapi,我们的团队使用Cosmos DB作为后端图形存储。基本上,由于gremlinapi的大小和步长限制,我们使用javagremlinsdk对顶点/边进行查询,并使用sqlsdk创建/更新顶点 我在尝试更新包含Long类型属性的顶点时遇到了这个问题。 在我们的代码中,我们使用CosmosDbElement和另一个标志作为输入参数,调用sqlClient.executestoreprocedure(“sp_name”,pk,new Object[]{document,flag}) 我使用的存储过程只是
CosmosDbElement
和另一个标志作为输入参数,调用sqlClient.executestoreprocedure(“sp_name”,pk,new Object[]{document,flag})代码>
我使用的存储过程只是执行一些验证,然后调用collection.replaceDocument()
替换文档
当我在此属性上设置不同的值时,我得到了不同的行为:
[-2^53+1,2^53-1](JavaScript中最小安全整数到最大安全整数)内的属性值
- 替换为SQL SDK,然后按ID获取:运行良好
- 替换为SP,然后按ID获取:运行良好
属性值超出上述范围且在Int64范围内
- 替换为SQL SDK,然后按ID获取:运行良好
- 替换为SP,然后按ID获取:最后3位四舍五入。例如
9223372036854775107->9223372036854775000
9223372036854775807->9223372036854776000
我们可以使用SQL SDK获得相同的舍入值
在大多数情况下,g.V([id])
获得相同的舍入值。
但如果舍入值超出了Int64
的范围,例如9223372036854775807->9223372036854776000,g.V([id])
抛出异常:无法在非基元类型biginger上创建ValueField
属性超出Int64的范围
- 替换为SQL SDK,然后按ID获取:运行良好
- 替换为SP,然后按ID获取:运行良好
我是否以正确的方式使用SP
这是设计上的限制还是问题
如何避免这种精度损失并能够查询顶点
如果您需要更多信息,请告诉我,谢谢
存储过程是用JavaScript编写的
正如您所知,JavaScript使用IEEE 754中指定的双精度浮点格式数字,它只能安全地保存介于-(2^53-1)
和2^53-1
(即9007199254740991
)之间的数字
因此,如果在JavaScript中使用存储过程将safeMIN\u safe\u INTEGER
之外的值替换为MAX\u safe\u INTEGER
,它将被舍入。这是设计上的限制
建议的解决办法是:
如果您对精度损失满意,则建议将Int64
值转换为双倍值,以便您的应用程序处理转换/舍入
如果需要保持精度,则使用字符串,缺点是算术运算不能应用于服务器端
存储过程是用JavaScript编写的
正如您所知,JavaScript使用IEEE 754中指定的双精度浮点格式数字,它只能安全地保存介于-(2^53-1)
和2^53-1
(即9007199254740991
)之间的数字
因此,如果在JavaScript中使用存储过程将safeMIN\u safe\u INTEGER
之外的值替换为MAX\u safe\u INTEGER
,它将被舍入。这是设计上的限制
建议的解决办法是:
如果您对精度损失满意,则建议将Int64
值转换为双倍值,以便您的应用程序处理转换/舍入
如果需要保持精度,则使用字符串,缺点是算术运算不能应用于服务器端