1

我们的团队正在使用 Cosmos DB 作为我们的后端图形存储。基本上,由于 Gremlin API 的大小和步长限制,我们使用 JAVA Gremlin SDK 对顶点/边进行查询,并使用 SQL SDK 创建/更新顶点。

我在尝试更新包含 Long 类型属性的顶点时遇到了这个问题。在我们的代码中,我们使用CosmosDbElement另一个标志作为输入参数,调用sqlClient.executeStoredProcedure(“sp_name”, pk, new Object[] { document, flag }); 我使用的存储过程只是进行一些验证,然后调用collection.replaceDocument()以替换文档。

当我在这个属性上设置不同的值时,我得到了不同的行为:

  1. [-2^53 + 1, 2 ^53 - 1] 内的属性值(JavaScript 中的 MIN_SAFE_INTEGER 到 MAX_SAFE_INTEGER)

    • 替换为 SQL SDK 然后通过 ID 获取:效果很好
    • 替换为 SP 然后通过 ID 获取:效果很好
  2. 超出上述范围且在 Int64 范围内的属性值

    • 替换为 SQL SDK 然后通过 ID 获取:效果很好
    • 替换为 SP 然后按 ID 获取:最后 3 位四舍五入。例如

             922337203685477 5107 -> 922337203685477 5000

             922337203685477 5807 -> 922337203685477 6000

             我们可以使用 SQL SDK 获得相同的舍入值。

             对于大多数情况g.V([id]),得到相同的舍入值。但是如果四舍五入的值超出 的范围Int64,比如 922337203685477 5807 -> 922337203685477 6000,就会g.V([id])抛出异常:Cannot create ValueField on non-primitive type BigInteger

  1. Int64 范围之外的属性
    • 替换为 SQL SDK 然后通过 ID 获取:效果很好
    • 替换为 SP 然后通过 ID 获取:效果很好

我是否以正确的方式使用 SP?

设计是限制还是问题?

如何避免这种精度损失并能够查询顶点?

如果您需要更多信息,请告诉我,谢谢。

4

1 回答 1

0

存储过程是用 JavaScript 编写的。

如您所知,JavaScript 使用 IEEE 754 中指定的双精度浮点格式数字,它只能安全​​地保存-(2^53 - 1)2^53-1(即9007199254740991)之间的数字。

因此,如果您使用 sproc 替换 JavaScript 中安全之外的值MIN_SAFE_INTEGERMAX_SAFE_INTEGER它将被四舍五入。这是一个设计限制。

推荐的解决方法是:

  1. 如果您对精度损失感到满意,则Int64建议将值转换为双精度值,以便您的应用程序处理转换/舍入。
  2. 如果您需要保持精度,请使用字符串,缺点是不能在服务器端应用算术运算。
于 2020-03-24T04:55:06.287 回答