Azure-sdk-for-js: [Cosmos DB] Really large numbers are getting rounded off

Created on 6 Feb 2021  路  3Comments  路  Source: Azure/azure-sdk-for-js

  • Package Name: @azure/cosmos
  • Package Version: 3.9.5
  • Operating system: macOS
  • [x] nodejs

    • version: 14.15.1

  • [ ] browser

    • name/version:

  • [ ] typescript

    • version:

  • Is the bug related to documentation in

Describe the bug
When fetching documents containing really large numbers, they are getting rounded off. For example, the value that is being saved is 9223372036854775807 however when fetching via Node SDK the value returned is 9223372036854776000. The same document when fetched via .Net SDK returns correct values though (i.e. no rounding off is happening there).

To Reproduce
Here's my code to save and retrieve the document using Cosmos .Net SDK (Microsoft.Azure.Cosmos version 3.16.0)

using System;
using Microsoft.Azure.Cosmos;
using Newtonsoft.Json;

namespace CosmosLongValuesTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var connectionString = "<connection-string>";
            var databaseName = "<database-name>";
            var containerName = "<container-name>";
            var client = new CosmosClient(connectionString);
            var db = client.GetDatabase(databaseName);
            var container = db.GetContainer(containerName);
            var model = new Model()
            {
                Id = Guid.NewGuid().ToString(),
                PartitionKey = "000",
                LongValue = Int64.MaxValue
            };
            var result = container.CreateItemAsync(model).GetAwaiter().GetResult();
            var item = container.ReadItemAsync<Model>(model.Id, new PartitionKey(model.PartitionKey)).GetAwaiter().GetResult();
            Console.WriteLine(item.Resource.LongValue);//prints 9223372036854775807

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
    }

    class Model
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        [JsonProperty("_partitionKey")]
        public string PartitionKey { get; set; }

        public Int64 LongValue { get; set; } 
    }
}

This code works perfectly fine. I am able to retrieve the same value that I saved.

Here's the code to retrieve document using Node SDK:

const {CosmosClient} = require('@azure/cosmos');

const endpoint = '<account-endpoint>';
const key = '<account-key>';
const databaseName = '<database-name>';
const containerName = '<container-name>';
const documentId = '<document-id>';
const partitionKey = '<document-partition-key>';

const client = new CosmosClient({endpoint, key});
const database = client.database(databaseName);
const container = database.container(containerName);
const documentToRead = container.item(documentId, partitionKey);
documentToRead.read()
.then((result) => {
  console.log(result.resource.LongValue);//prints 9223372036854776000
})
.catch((error) => {
  console.log(error);
});

Expected behavior
Long values should not be rounded off. Considering the value returned by .Net SDK is correct, my assumption is that it is being stored properly in Cosmos.

Additional context
More than likely the issue is coming because of how long numbers are treated in JavaScript. As per the documentation here, max safe integer value is 2^53 - 1 which is 9007199254740991 (much smaller than .Net Int64.MaxValue).

customer-reported needs-triage question

All 3 comments

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @southpolesteve, @zfoster

@gmantri This expected behavior. The Cosmos service meets the JSON spec which does not put specific limits on number types but suggests being compliant with IEEE754. So yes, Cosmos is capable of representing large integers, but caution should be used as these are not compatible with all languages and runtimes. The behavior you are describing is a fundamental limitation of the JavaScript language.

If you want to store these values in Cosmos you need to store them as strings. You can always parse them to BigInt if your JavaScript runtime has BigInt support.

I've tried three CosmosDB tools: Cerebrata Cerulean, Azure Storage Explorer, and the Azure web portal, and none of them can properly display the Int64 value stored in the database. I spent quite some time trying to figure out if I was going crazy. Turns out the culprit was JavaScript. I should have known.

Was this page helpful?
0 / 5 - 0 ratings