0

I have one extended json string.

{"_id": {"oid": "59a47286cfa9a3a73e51e72c"}, "theaterId": {"numberInt": "101100"}, "location": {"address": {"street1": "340 XDW Market", "city": "Bloomington", "state": "MN", "zipcode": "12427"}, "geo": {"type": "Point", "coordinates": [{"$numberDouble": "-193.24565"}, {"$numberDouble": "144.85466"}]}}}

Trying to convert above json string to document in order to insert it into MongoDB. For this I am using org.bson.Document.Document.parse(json_string) constructor.

But the document I am getting after parsing, doesn't preserve the datatype inside geo.coordinate arraylist (Check below Document). While it preserve datatype of theaterId.

{
    "_id": {
        "oid": "59a47286cfa9a3a73e51e72c"
    },
    "theaterId": {
        "numberInt": "101100"
    },
    "location": {
        "address": {
            "street1": "340 XDW Market",
            "city": "Bloomington",
            "state": "MN",
            "zipcode": "12427"
        },
        "geo": {
            "type": "Point",
            "coordinates": [-193.24565, 144.85466]
        }
    }
}

Is this a potential issue in Document.parse() API ?

Dunggeon
  • 92
  • 1
  • 1
  • 11

1 Answers1

1

Your fields in geo.coordinate are starting with dollar sign $. In theaterId you have numberInt, while in coordinate - $numberDouble.

Check the docs and this question for how to handle it depending on what you need. Considering, that it looks like numberInt satisfies your needs, you might just need to remove the dollars from field names.

Edit: After digging somewhat deeper into those docs, the one you provided as well, {"numberInt": "101100"} is not extended json with datatype, it's just a normal json object with property and value for that property. It would need to be {"$numberInt": "101100"} to be extended json. On the other hand {"$numberDouble": "-193.24565"} is extended. The datatype is not lost, it's parsed into List<Double>, since we know each element is of type Double the datatype can be reconstructed back.

If you take at Document.toJson(), under the hood it's working with RELAXED output mode, which will output coordinates as you are seeing them - [-193.24565, 144.85466]. If you provide EXTENDED output mode, for example like this:

JsonWriterSettings settings = JsonWriterSettings.builder().outputMode(JsonMode.EXTENDED).build();
System.out.println(document.toJson(settings));

then the datatype will be reconstructed back from the java type, and coordinates will look like so:

[{"$numberDouble": "-193.24565"}, {"$numberDouble": "144.85466"}]

In conclusion, there is no problem with Document.parse("json"), but there might be a problem with the json you are supplying to it.

Edit2: As in showed in example, the datatypes can be reconstructed back from java types. I am not familiar with the way collection.insertOne(Document.parse(json_string)) works under the hood, but if you don't explicitly specify the mode, it might be using RELAXED by default, instead of EXTENDED. The docs here state - This format prioritizes type preservation at the loss of human-readability and interoperability with older formats., so it would make sense. But this is just a wild guess on my part though, you would need to dig into docs to make sure.

Chaosfire
  • 4,818
  • 4
  • 8
  • 23
  • Thanks @Chaosfire , meanwhile your answer seems to correct but my issue is due to MongoDB Extended JSON feature. [MongoDB Extended JSON](https://docs.mongodb.com/v4.4/reference/mongodb-extended-json/) – Dunggeon Feb 25 '22 at 10:56
  • @PiyushKumar There is no problem with the API, check the edit. – Chaosfire Feb 25 '22 at 12:49
  • Hi @Chaosfire I have one doubt. Suppose I have a json string which is in its canonical (extended) form. If I insert that json string from mongo shell using _db.collectionName.insertOne(json)_ then the type ( **"$numberDouble"** ) is preserved. While I insert the same string using java API _collection.insertOne(Document.parse(json_string))_ then it doesn't preserve type. Please Note :- Consider above json string for now in this doubt (replace **numberInt** to **$numberInt** ) – Dunggeon Feb 26 '22 at 09:13
  • @PiyushKumar Things became too long for comment, so i made another edit, check it. I believe this is a matter of configuration, but might be wrong, since i am mostly speculating here. – Chaosfire Feb 26 '22 at 11:45