orlandos-nl / MongoKitten

Native MongoDB driver for Swift, written in Swift

Home Page:https://orlandos.nl/docs/mongokitten/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

An empty json object/dictionary is encoded as an empty array. MongoKitten 4.1.2

icyield opened this issue · comments

An empty dictionary is encoded as an empty array. MongoKitten 4.1.2

The String ...
"{\n "updatedAt" : "1522766879624",\n "_id" : "5ac3941f863e96c585ad58b8",\n "tags" : {\n\n },\n "tagsUpdate" : true\n}"

Ends up as.
▿ some : {"updatedAt":"1522766879624","_id":"5ac3941f863e96c585ad58b8","tags":[],"tagsUpdate":true}

The json object seems to be parse correctly.

  • key : "tags"
    ▿ value : JSONObject
    - storage : 0 elements

But the Document ends up with an empty array.

Thanks. Details below.

let json = try? Cheetah.JSON.parse(from: redisResult)
let jsonDoc = try MongoKitten.Document(extendedJSON:redisResult )

Printing description of redisResult:
"{\n "updatedAt" : "1522766879624",\n "_id" : "5ac3941f863e96c585ad58b8",\n "tags" : {\n\n },\n "tagsUpdate" : true\n}"

Printing description of json:
▿ Optional
▿ some : JSONObject
▿ storage : 4 elements
▿ 0 : 2 elements
- key : "updatedAt"
- value : "1522766879624"
▿ 1 : 2 elements
- key : "_id"
- value : "5ac3941f863e96c585ad58b8"
▿ 2 : 2 elements
- key : "tags"
▿ value : JSONObject
- storage : 0 elements
▿ 3 : 2 elements
- key : "tagsUpdate"
- value : true

Printing description of jsonDoc:
▿ Optional
▿ some : {"updatedAt":"1522766879624","_id":"5ac3941f863e96c585ad58b8","tags":[],"tagsUpdate":true}
▿ isArray : Optional
- some : false
▿ storage : 87 elements

Thank you for the report, I think I know where it's coming from already.

Hi,
actually I think it is trying to be too clever. In the the String below, tags is converted into an array too. If instead of "1":"2" it is "one":"two" then everything is as expected.

Printing description of redisResult:
"{\n "updatedAt" : "1522766879624",\n "_id" : "5ac3941f863e96c585ad58b8",\n "tags" : {\n"1":"2"\n },\n "tagsUpdate" : true\n}"

Printing description of jsonDoc:
▿ Optional
▿ some : {"updatedAt":"1522766879624","_id":"5ac3941f863e96c585ad58b8","tags":["2"],"tagsUpdate":true}

Regards

Details below.

let json = try? Cheetah.JSON.parse(from: redisResult)
let jsonDoc = try MongoKitten.Document(extendedJSON:redisResult )

Printing description of redisResult:
"{\n "updatedAt" : "1522766879624",\n "_id" : "5ac3941f863e96c585ad58b8",\n "tags" : {\n"1":"2"\n },\n "tagsUpdate" : true\n}"

Printing description of json:
▿ Optional
▿ some : JSONObject
▿ storage : 4 elements
▿ 0 : 2 elements
- key : "updatedAt"
- value : "1522766879624"
▿ 1 : 2 elements
- key : "_id"
- value : "5ac3941f863e96c585ad58b8"
▿ 2 : 2 elements
- key : "tags"
▿ value : JSONObject
▿ storage : 1 element
▿ 0 : 2 elements
- key : "1"
- value : "2"
▿ 3 : 2 elements
- key : "tagsUpdate"
- value : true
Printing description of jsonDoc:
▿ Optional
▿ some : {"updatedAt":"1522766879624","_id":"5ac3941f863e96c585ad58b8","tags":["2"],"tagsUpdate":true}

That's expected behaviour to some degree, I'm afraid, and cannot be fixed in the current MongoKitten version.

MongoDB Documents are a [(String, Primitive)] meaning they're both an array and a dictionary at the same time. You can subscript it like a dictionary which will get the element's primitive (right value) where the key (left value) is the same string.

However, the arrays are normally an integer expressed as ASCII/UTF-8 which is then used for a key.

hmmmm... MongoDB (at least via Robo 3T) seems happy with
{
"_id" : "5ac3941f863e96c585ad58b8",
"tags" : {
"1" : "2"
}
}

via MongoKitten that becomes
{
"_id" : "5ac3941f863e96c585ad58b8",
"tags" : [
undefined,
"2"
]
}

but larger numbers might cause issues! "10":"2" becomes
{
"_id" : "5ac3941f863e96c585ad58b8",
"tags" : [
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
"2"
]
}

But at least,
"tags" : {
"10" : "2",
"ten" : "2"
}
Seems to work. So I guess I will have to add a dummy key which is not an integer to get the behaviour I need.

What is "undefined"?

That is the json I get from Robo 3T when looking at the entry in mongoDB.
Because the code is interpreting "10":"2" as an array, it means to mongoDB an array of 11 element with element index 10 as 2. Other elements are undefined.

So for {"100":"2"} a 101 element array is generated!