duancan9815 2019-02-18 13:31
浏览 150
已采纳

从map [string] interface {}插入JSON或地图到MongoDB集合会设置int并以字符串形式浮动

I know the title seems generic and a duplicate, but i've tried many of the options from previous questions, and I can't use a struct here

My system is using the messaging service NATS to sends maps between a subscriber and a publisher. The subscriber takes the received map, and inserts it as a document in a MongoDB collection

The problem I have is that floats and ints are inserted as strings!

In my code, the recipe is a configuration file that sets the datatypes of the columns received in the map. Think of it as a series of keys like this:

  • String column: "string",
  • Int column: "int"

Here's the code that creates the map with the right datatypes

mapWithCorrectDataTypes := make(map[string]interface{})

    for columnNameFromDataTypesInRecipe, datatypeForColumnInRecipe := range dataTypesFromRecipeForColumns {

    for natsMessageColumn, natsMessageColumnValue := range mapFromNATSMessage {

            //If the column in the NATS message is found in the recipe, format the data as dictated in the recipe
                    if natsMessageColumn == columnNameFromDataTypesInRecipe {

                        if datatypeForColumnInRecipe.(string) == "string" {

                            natsMessageColumnValue = natsMessageColumnValue.(string)
                            mapWithCorrectDataTypes[columnNameFromDataTypesInRecipe] = natsMessageColumnValue
                        }

                        if datatypeForColumnInRecipe.(string) == "int" {

                            convertedInt, err := strconv.Atoi(mapFromNATSMessage[columnNameFromDataTypesInRecipe].(string))
                            if err != nil {
                                fmt.Println("ERROR -->", err)
                            }
                            mapWithCorrectDataTypes[columnNameFromDataTypesInRecipe] = convertedInt
                        }

                        if datatypeForColumnInRecipe.(string) == "float64" {

                            convertedFloat, err := strconv.ParseFloat(mapFromNATSMessage[columnNameFromDataTypesInRecipe].(string), 64)

                            if err != nil {
                                fmt.Println("ERROR -->", err)
                            }
                            mapWithCorrectDataTypes[columnNameFromDataTypesInRecipe] = convertedFloat

                            fmt.Println("TYPE -->", reflect.TypeOf(mapWithCorrectDataTypes[columnNameFromDataTypesInRecipe]))
                        }
                    } else {
                        //If column not found in the recipe, format as a string
                        mapWithCorrectDataTypes[natsMessageColumn] = natsMessageColumnValue.(string)
                    }
                }
            }

From the last line I put in a print statement for float64s to check that the datatype for this key in the map is correct, and it passes this test!


My question is this: If the data types are correctly being set in the map, why when the map is inserted as a document in MongoDB are the floats and ints set as strings?!

What I have tried so far:

Marshalling and unmarshalling the map as an interface, then inserting the record:

        jsonVersionOfMap, err := json.Marshal(mapWithCorrectDataTypes)

        if err != nil {
            fmt.Println("ERROR -->", err)
        }

        var interfaceForJSON interface{}

        json.Unmarshal(jsonVersionOfMap, &interfaceForJSON)

        fmt.Println("JSON -->", interfaceForJSON)
        err = mongoConnection.Insert(interfaceForJSON)

        if err != nil {
            fmt.Println("Error inserting MongoDB documents", err)
        }

What am I missing here?

See the result with the incorrectly formatted data:

enter image description here

  • 写回答

1条回答 默认 最新

  • doujilou3903 2019-02-19 00:10
    关注

    this may not be a fix. But i've resolved the issue i've been having. I'm using a publisher and a subscriber via NATS. Previously I was creating a map with all the data, then sending that out as a message, then the subscriber takes the map from the message, and processing the datatypes (on the subscriber side)

    To fix the problem that I was experiencing, I instead formatted the maps' values on the publisher side. So I instead moved my code that checks for the datatype over to the NATS publisher, and not the code that processes the incoming message

    I understand this isn't an ideal solution, but if you're using NATS and find you're having the same issue. Try this

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料