Azure cosmosdb 处理长整数类型时SQL SDK和存储过程之间的不一致

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}) 我使用的存储过程只是

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

我在尝试更新包含Long类型属性的顶点时遇到了这个问题。 在我们的代码中,我们使用
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中使用存储过程将safe
    MIN\u safe\u INTEGER
    之外的值替换为
    MAX\u safe\u INTEGER
    ,它将被舍入。这是设计上的限制

    建议的解决办法是:

  • 如果您对精度损失满意,则建议将
    Int64
    值转换为双倍值,以便您的应用程序处理转换/舍入
  • 如果需要保持精度,则使用字符串,缺点是算术运算不能应用于服务器端
  • 存储过程是用JavaScript编写的

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

    因此,如果在JavaScript中使用存储过程将safe
    MIN\u safe\u INTEGER
    之外的值替换为
    MAX\u safe\u INTEGER
    ,它将被舍入。这是设计上的限制

    建议的解决办法是:

  • 如果您对精度损失满意,则建议将
    Int64
    值转换为双倍值,以便您的应用程序处理转换/舍入
  • 如果需要保持精度,则使用字符串,缺点是算术运算不能应用于服务器端