0

Insert Interface data with integer and double fields via Golang to MongoDB but integer fields was stored as double

I have to consume unstructure data from queue (JSON format) and bulk the data to MongoDB but the integer fields was store as double

Example Code

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    mongoURI := fmt.Sprintf("mongodb://%s:%s@%s:%d", "root", "root", "localhost", 27017)
    ctxtimeout, cancelCtx := context.WithTimeout(context.Background(), 60*time.Second)
    mongoConnection, err := mongo.NewClient(options.Client().ApplyURI(mongoURI))
    if err != nil {
        log.Fatal(err.Error())
    }
    defer cancelCtx()
    err = mongoConnection.Connect(ctxtimeout)
    if err != nil {
        log.Fatal(err.Error())
    }
    defer mongoConnection.Disconnect(ctxtimeout)
    mongoDatabase := mongoConnection.Database("dbname")
    mongoCollection := mongoDatabase.Collection("posts")

    str := `{ "number1": 10, "number2": 20.1 }`
    var data map[string]interface{}
    json.Unmarshal([]byte(str), &data)
    reMar, _ := json.Marshal(data)
    fmt.Println(string(reMar))
    mongoCollection.InsertOne(ctxtimeout, data)
}

The str variable is store the example data that I got from queue

This is the output that store to MongoDB. The number1 fields should stored as Int but it stored as Double

So, How to stored it as Int not double ?

output when store to mongo

3
  • related: stackoverflow.com/questions/8218484/… Commented Oct 15, 2021 at 10:09
  • @Andy Yes, Thank for your comment but the worker that I designed It never know the data type it just consume and bulk the data to collection. Commented Oct 15, 2021 at 10:21
  • Go, when unmarshaling a JSON Number into an interface{}, will by default use the float64 type, regardless of the Number's value. See play.golang.org/p/2qhLIWF7u_j. If you want to store integers in Mongo, using JSON Numbers as the source data, do not use interface{} for unmarshaling that JSON. Commented Oct 15, 2021 at 10:26

1 Answer 1

1

I just found solution by using json.NewDecoder with UseNumber()

Example code

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "strings"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    mongoURI := fmt.Sprintf("mongodb://%s:%s@%s:%d", "root", "root", "localhost", 27017)
    ctxtimeout, cancelCtx := context.WithTimeout(context.Background(), 60*time.Second)
    mongoConnection, err := mongo.NewClient(options.Client().ApplyURI(mongoURI))
    if err != nil {
        log.Fatal(err.Error())
    }
    defer cancelCtx()
    err = mongoConnection.Connect(ctxtimeout)
    if err != nil {
        log.Fatal(err.Error())
    }
    defer mongoConnection.Disconnect(ctxtimeout)
    mongoDatabase := mongoConnection.Database("influencerdirectory")
    mongoCollection := mongoDatabase.Collection("posts")

    str := `{ "number1": 10, "number2": 20.1 }`
    var data map[string]interface{}
    d := json.NewDecoder(strings.NewReader(str))
    d.UseNumber()
    d.Decode(&data)
    // json.Unmarshal([]byte(str), &data)
    reMar, _ := json.Marshal(data)
    fmt.Println(string(reMar))
    mongoCollection.InsertOne(ctxtimeout, data)
}

Result:

enter image description here

Ref : Need to parse integers in JSON as integers, not floats

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.