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!